From b3175db3a3202d025971301ebec704ed8676252a Mon Sep 17 00:00:00 2001 From: Andrew Mickelson Date: Thu, 5 Jan 2017 22:08:14 -0800 Subject: [PATCH] [linux] fixes for multimonitor mode with X11 - always use xinerama if available to determine the screen dimensions - use Xlib to determine screen size if xinerama isn't available --- Makefile | 23 ++++++++++++++++------- src/fe_present.cpp | 38 ++++++++++++++++++++++++-------------- src/fe_util.cpp | 41 ++++++++++++++++++++++++++++++----------- src/fe_util.hpp | 4 ++-- src/fe_window.cpp | 29 ++++++++++++++++++++--------- 5 files changed, 92 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 84ca2bcbb..e28e19d0b 100644 --- a/Makefile +++ b/Makefile @@ -180,10 +180,13 @@ ifneq ($(FE_WINDOWS_COMPILE),1) USE_GLES=1 else # - # Test for Xinerama... + # Test for Xlib and Xinerama... # - ifeq ($(shell $(PKG_CONFIG) --exists xinerama && echo "1" || echo "0"), 1) - USE_XINERAMA=1 + ifeq ($(shell $(PKG_CONFIG) --exists x11 && echo "1" || echo "0"), 1) + USE_XLIB=1 + ifeq ($(shell $(PKG_CONFIG) --exists xinerama && echo "1" || echo "0"), 1) + USE_XINERAMA=1 + endif endif endif endif @@ -241,7 +244,7 @@ ifneq ($(NO_SWF),1) LIBS += -ldl -lGL endif TEMP_LIBS += freetype2 - CFLAGS += $(shell $(PKG_CONFIG) --cflags --silence-errors) + CFLAGS += $(shell $(PKG_CONFIG) --cflags --silence-errors freetype2) endif else LIBS += -lopengl32 @@ -299,9 +302,15 @@ ifeq ($(USE_GLES),1) FE_FLAGS += -DUSE_GLES endif -ifeq ($(USE_XINERAMA),1) - FE_FLAGS += -DUSE_XINERAMA - LIBS += -lX11 -lXinerama +ifeq ($(USE_XLIB),1) + FE_FLAGS += -DUSE_XLIB + LIBS += -lX11 + + ifeq ($(USE_XINERAMA),1) + FE_FLAGS += -DUSE_XINERAMA + LIBS += -lXinerama + endif + endif ifeq ($(USE_FONTCONFIG),1) diff --git a/src/fe_present.cpp b/src/fe_present.cpp index ec8bc337c..224aa801b 100644 --- a/src/fe_present.cpp +++ b/src/fe_present.cpp @@ -161,7 +161,7 @@ void FePresent::init_monitors() // // We support multi-monitor setups on MS-Windows when in fullscreen or "fillscreen" mode // -#ifdef SFML_SYSTEM_WINDOWS +#if defined(SFML_SYSTEM_WINDOWS) if ( m_feSettings->get_info_bool( FeSettings::MultiMon ) && !is_windowed_mode( m_feSettings->get_window_mode() ) ) { @@ -178,10 +178,8 @@ void FePresent::init_monitors() (*itr).transform *= correction; } else -#else -#ifdef USE_XINERAMA - if ( m_feSettings->get_info_bool( FeSettings::MultiMon ) - && !is_windowed_mode( m_feSettings->get_window_mode() ) ) +#elif defined(USE_XINERAMA) + if ( 1 ) { Display *xdisp = XOpenDisplay( NULL ); int num=0; @@ -189,16 +187,29 @@ void FePresent::init_monitors() XineramaScreenInfo *si=XineramaQueryScreens( xdisp, &num ); if ( si ) { - for ( int i=0; iget_info_bool( FeSettings::MultiMon ) ) + && ( !is_windowed_mode( m_feSettings->get_window_mode() ))) + { + for ( int i=0; i +#ifdef USE_XLIB +#include + #ifdef USE_XINERAMA + #include + #endif #endif + namespace { void str_from_c( std::string &s, const char *c ) @@ -1047,13 +1051,13 @@ std::basic_string clipboard_get_content() return retval; } -#ifdef USE_XINERAMA +#if defined(USE_XLIB) // // We use this in fe_window but implement it here because the XWindows // namespace (Window, etc) clashes with the SFML namespace used in fe_window // (sf::Window) // -void get_xinerama_geometry( int &x, int &y, int &width, int &height ) +void get_x11_geometry( bool multimon, int &x, int &y, int &width, int &height ) { x=0; y=0; @@ -1063,21 +1067,36 @@ void get_xinerama_geometry( int &x, int &y, int &width, int &height ) ::Display *xdisp = XOpenDisplay( NULL ); int num=0; +#ifdef USE_XINERAMA XineramaScreenInfo *si=XineramaQueryScreens( xdisp, &num ); - if ( num > 1 ) + if ( multimon ) { - x=-si[0].x_org; - y=-si[0].y_org; - } + if ( num > 1 ) + { + x=-si[0].x_org; + y=-si[0].y_org; + } - for ( int i=0; i clipboard_get_content(); // namespace (Window, etc) clashes with the SFML namespace used in fe_window // (sf::Window) // -#ifdef USE_XINERAMA -void get_xinerama_geometry( int &, int &, int &, int & ); +#if defined(USE_XLIB) +void get_x11_geometry( bool multimon, int &, int &, int &, int & ); #endif #ifndef NO_MOVIE diff --git a/src/fe_window.cpp b/src/fe_window.cpp index 894acecd2..970f770d2 100644 --- a/src/fe_window.cpp +++ b/src/fe_window.cpp @@ -153,17 +153,23 @@ void FeWindow::onCreate() ShowWindow(hw, SW_SHOW); SetFocus( hw ); -#endif -#ifdef USE_XINERAMA - if ( m_fes.get_info_bool( FeSettings::MultiMon ) ) - { - int x, y, width, height; - get_xinerama_geometry( x, y, width, height ); +#elif defined(USE_XLIB) + // + // Notes: if xinerama and multimon are enabled, this should set our window to cover all available + // monitors + // + // If multimon is disabled, this fixes positioning problems that SFML(?) seems to have where + // the window contents aren't drawn in the correct place vertically on fullscreen/fillscreen modes + // + int x, y, width, height; + get_x11_geometry( + m_fes.get_info_bool( FeSettings::MultiMon ) && !is_windowed_mode( m_fes.get_window_mode() ), + x, y, width, height ); + + setPosition( sf::Vector2i( x, y ) ); + setSize( sf::Vector2u( width, height ) ); - setPosition( sf::Vector2i( x, y ) ); - setSize( sf::Vector2u( width, height ) ); - } #endif setVerticalSyncEnabled(true); @@ -186,6 +192,11 @@ void FeWindow::initial_create() int win_mode = m_fes.get_window_mode(); +#ifdef USE_XINERAMA + if ( m_fes.get_info_bool( FeSettings::MultiMon ) && ( win_mode != FeSettings::Default )) + std::cout << " ! NOTE: Use the 'Fill Screen' window mode if you want multiple monitor support to function correctly" << std::endl; +#endif + // Create window create( sf::VideoMode::getDesktopMode(),