You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
10 KiB
274 lines
10 KiB
From 83dd316f42bcc959a533e6be2ba24bbc37417a0a Mon Sep 17 00:00:00 2001
|
|
From: David Tardon <dtardon@redhat.com>
|
|
Date: Wed, 25 Apr 2012 15:08:53 +0200
|
|
Subject: [PATCH] rhbz#809019 count mirrored monitors as one
|
|
|
|
Change-Id: I I I184541e99ab4e04b8534dd0341bc2f3630094e9c
|
|
---
|
|
vcl/inc/unx/gtk/gtkdata.hxx | 2 +
|
|
vcl/inc/unx/gtk/gtksys.hxx | 11 ++++-
|
|
vcl/unx/gtk/app/gtkdata.cxx | 2 +
|
|
vcl/unx/gtk/app/gtksys.cxx | 85 ++++++++++++++++++++++++++++++--------
|
|
vcl/unx/gtk/window/gtkframe.cxx | 4 +-
|
|
5 files changed, 81 insertions(+), 23 deletions(-)
|
|
|
|
diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx
|
|
index 63b8ae3..033bf1a 100644
|
|
--- a/vcl/inc/unx/gtk/gtkdata.hxx
|
|
+++ b/vcl/inc/unx/gtk/gtkdata.hxx
|
|
@@ -151,6 +151,8 @@ public:
|
|
GdkDisplay* GetGdkDisplay() const { return m_pGdkDisplay; }
|
|
bool IsX11Display() const { return m_bX11Display; }
|
|
|
|
+ GtkSalSystem* getSystem() const { return m_pSys; }
|
|
+
|
|
virtual void deregisterFrame( SalFrame* pFrame );
|
|
GdkCursor *getCursor( PointerStyle ePointerStyle );
|
|
virtual int CaptureMouse( SalFrame* pFrame );
|
|
diff --git a/vcl/inc/unx/gtk/gtksys.hxx b/vcl/inc/unx/gtk/gtksys.hxx
|
|
index df9e79e..582d4b9 100644
|
|
--- a/vcl/inc/unx/gtk/gtksys.hxx
|
|
+++ b/vcl/inc/unx/gtk/gtksys.hxx
|
|
@@ -33,10 +33,15 @@
|
|
#include "generic/gensys.h"
|
|
#include <gtk/gtk.h>
|
|
#include <unx/saltype.h>
|
|
+#include <deque>
|
|
|
|
class GtkSalSystem : public SalGenericSystem
|
|
{
|
|
+ typedef std::deque<std::pair<GdkScreen*, int> > ScreenMonitors_t;
|
|
+
|
|
GdkDisplay *mpDisplay;
|
|
+ // Number of monitors for every active screen.
|
|
+ ScreenMonitors_t maScreenMonitors;
|
|
public:
|
|
GtkSalSystem();
|
|
virtual ~GtkSalSystem();
|
|
@@ -56,10 +61,11 @@
|
|
{ return getXScreenFromDisplayScreen( GetDisplayDefaultScreen() ); }
|
|
int GetDisplayXScreenCount();
|
|
SalX11Screen getXScreenFromDisplayScreen(unsigned int nDisplayScreen);
|
|
+ void countScreenMonitors();
|
|
// We have a 'screen' number that is combined from screen-idx + monitor-idx
|
|
- static int getScreenIdxFromPtr (GdkDisplay *pDisplay, GdkScreen *pScreen);
|
|
- static int getScreenMonitorIdx (GdkDisplay *pDisplay, GdkScreen *pScreen, int nX, int nY);
|
|
- static GdkScreen *getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMonitor);
|
|
+ int getScreenIdxFromPtr (GdkScreen *pScreen);
|
|
+ int getScreenMonitorIdx (GdkScreen *pScreen, int nX, int nY);
|
|
+ GdkScreen *getScreenMonitorFromIdx (int nIdx, gint &nMonitor);
|
|
};
|
|
|
|
#endif // _VCL_GTKSYS_HXX_
|
|
diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx
|
|
index 5189174..4d58110 100644
|
|
--- a/vcl/unx/gtk/app/gtkdata.cxx
|
|
+++ b/vcl/unx/gtk/app/gtkdata.cxx
|
|
@@ -197,12 +197,14 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event,
|
|
|
|
void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen )
|
|
{
|
|
+ m_pSys->countScreenMonitors();
|
|
if (pScreen)
|
|
emitDisplayChanged();
|
|
}
|
|
|
|
void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen )
|
|
{
|
|
+ m_pSys->countScreenMonitors();
|
|
if (pScreen)
|
|
emitDisplayChanged();
|
|
}
|
|
diff --git a/vcl/unx/gtk/app/gtksys.cxx b/vcl/unx/gtk/app/gtksys.cxx
|
|
index 538107f..25578b3 100644
|
|
--- a/vcl/unx/gtk/app/gtksys.cxx
|
|
+++ b/vcl/unx/gtk/app/gtksys.cxx
|
|
@@ -49,6 +49,7 @@ SalSystem *GtkInstance::CreateSalSystem()
|
|
GtkSalSystem::GtkSalSystem() : SalGenericSystem()
|
|
{
|
|
mpDisplay = gdk_display_get_default();
|
|
+ countScreenMonitors();
|
|
}
|
|
|
|
GtkSalSystem::~GtkSalSystem()
|
|
@@ -61,6 +62,52 @@ GtkSalSystem::GetDisplayXScreenCount()
|
|
return gdk_display_get_n_screens (mpDisplay);
|
|
}
|
|
|
|
+namespace
|
|
+{
|
|
+
|
|
+struct GdkRectangleEqual
|
|
+{
|
|
+ bool operator()(GdkRectangle const& rLeft, GdkRectangle const& rRight)
|
|
+ {
|
|
+ return
|
|
+ rLeft.x == rRight.x
|
|
+ && rLeft.y == rRight.y
|
|
+ && rLeft.width == rRight.width
|
|
+ && rLeft.height == rRight.height
|
|
+ ;
|
|
+ }
|
|
+};
|
|
+
|
|
+}
|
|
+
|
|
+void
|
|
+GtkSalSystem::countScreenMonitors()
|
|
+{
|
|
+ maScreenMonitors.clear();
|
|
+ for (gint i = 0; i < gdk_display_get_n_screens(mpDisplay); i++)
|
|
+ {
|
|
+ GdkScreen* const pScreen(gdk_display_get_screen(mpDisplay, i));
|
|
+ gint nMonitors(pScreen ? gdk_screen_get_n_monitors(pScreen) : 0);
|
|
+ if (nMonitors > 1)
|
|
+ {
|
|
+ std::vector<GdkRectangle> aGeometries;
|
|
+ aGeometries.reserve(nMonitors);
|
|
+ for (gint j(0); j != nMonitors; ++j)
|
|
+ {
|
|
+ GdkRectangle aGeometry;
|
|
+ gdk_screen_get_monitor_geometry(pScreen, j, &aGeometry);
|
|
+ aGeometries.push_back(aGeometry);
|
|
+ }
|
|
+ GdkRectangleEqual aCmp;
|
|
+ std::sort(aGeometries.begin(), aGeometries.end(), aCmp);
|
|
+ const std::vector<GdkRectangle>::iterator aUniqueEnd(
|
|
+ std::unique(aGeometries.begin(), aGeometries.end(), aCmp));
|
|
+ nMonitors = std::distance(aGeometries.begin(), aUniqueEnd);
|
|
+ }
|
|
+ maScreenMonitors.push_back(std::make_pair(pScreen, nMonitors));
|
|
+ }
|
|
+}
|
|
+
|
|
// Including gdkx.h kills us with the Window / XWindow conflict
|
|
extern "C" {
|
|
GType gdk_x11_display_get_type (void);
|
|
@@ -73,7 +120,7 @@ GtkSalSystem::getXScreenFromDisplayScreen(unsigned int nScreen)
|
|
gint nMonitor;
|
|
GdkScreen *pScreen = NULL;
|
|
|
|
- pScreen = getScreenMonitorFromIdx (mpDisplay, nScreen, nMonitor);
|
|
+ pScreen = getScreenMonitorFromIdx (nScreen, nMonitor);
|
|
if (!pScreen)
|
|
return SalX11Screen (0);
|
|
#if GTK_CHECK_VERSION(3,0,0)
|
|
@@ -84,16 +131,16 @@ GtkSalSystem::getXScreenFromDisplayScreen(unsigned int nScreen)
|
|
}
|
|
|
|
GdkScreen *
|
|
-GtkSalSystem::getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMonitor)
|
|
+GtkSalSystem::getScreenMonitorFromIdx (int nIdx, gint &nMonitor)
|
|
{
|
|
GdkScreen *pScreen = NULL;
|
|
- for (gint i = 0; i < gdk_display_get_n_screens (pDisplay); i++)
|
|
+ for (ScreenMonitors_t::const_iterator aIt(maScreenMonitors.begin()), aEnd(maScreenMonitors.end()); aIt != aEnd; ++aIt)
|
|
{
|
|
- pScreen = gdk_display_get_screen (pDisplay, i);
|
|
+ pScreen = aIt->first;
|
|
if (!pScreen)
|
|
break;
|
|
- if (nIdx >= gdk_screen_get_n_monitors (pScreen))
|
|
- nIdx -= gdk_screen_get_n_monitors (pScreen);
|
|
+ if (nIdx >= aIt->second)
|
|
+ nIdx -= aIt->second;
|
|
else
|
|
break;
|
|
}
|
|
@@ -102,32 +149,34 @@ GtkSalSystem::getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMo
|
|
}
|
|
|
|
int
|
|
-GtkSalSystem::getScreenIdxFromPtr (GdkDisplay *pDisplay, GdkScreen *pScreen)
|
|
+GtkSalSystem::getScreenIdxFromPtr (GdkScreen *pScreen)
|
|
{
|
|
int nIdx = 0;
|
|
- for (gint i = 0; i < gdk_display_get_n_screens (pDisplay); i++)
|
|
+ for (ScreenMonitors_t::const_iterator aIt(maScreenMonitors.begin()), aEnd(maScreenMonitors.end()); aIt != aEnd; ++aIt)
|
|
{
|
|
- GdkScreen *pCmp = gdk_display_get_screen (pDisplay, i);
|
|
- if (pCmp == pScreen)
|
|
+ if (aIt->first == pScreen)
|
|
return nIdx;
|
|
- nIdx += gdk_screen_get_n_monitors (pCmp);
|
|
+ nIdx += aIt->second;
|
|
}
|
|
g_warning ("failed to find screen %p", pScreen);
|
|
return 0;
|
|
}
|
|
|
|
-int GtkSalSystem::getScreenMonitorIdx (GdkDisplay *pDisplay,
|
|
- GdkScreen *pScreen,
|
|
+int GtkSalSystem::getScreenMonitorIdx (GdkScreen *pScreen,
|
|
int nX, int nY)
|
|
{
|
|
- return getScreenIdxFromPtr (pDisplay, pScreen) +
|
|
+ // TODO: this will fail horribly for exotic combinations like two
|
|
+ // monitors in mirror mode and one extra. Hopefully such
|
|
+ // abominations are not used (or, even better, not possible) in
|
|
+ // practice .-)
|
|
+ return getScreenIdxFromPtr (pScreen) +
|
|
gdk_screen_get_monitor_at_point (pScreen, nX, nY);
|
|
}
|
|
|
|
unsigned int GtkSalSystem::GetDisplayScreenCount()
|
|
{
|
|
gint nMonitor;
|
|
- (void)getScreenMonitorFromIdx (mpDisplay, G_MAXINT, nMonitor);
|
|
+ (void)getScreenMonitorFromIdx (G_MAXINT, nMonitor);
|
|
return G_MAXINT - nMonitor;
|
|
}
|
|
|
|
@@ -183,7 +232,7 @@ static int _get_primary_monitor (GdkScreen *pScreen)
|
|
unsigned int GtkSalSystem::GetDisplayDefaultScreen()
|
|
{
|
|
GdkScreen *pDefault = gdk_display_get_default_screen (mpDisplay);
|
|
- int idx = getScreenIdxFromPtr (mpDisplay, pDefault);
|
|
+ int idx = getScreenIdxFromPtr (pDefault);
|
|
return idx + _get_primary_monitor (pDefault);
|
|
}
|
|
|
|
@@ -192,7 +241,7 @@ Rectangle GtkSalSystem::GetDisplayScreenPosSizePixel (unsigned int nScreen)
|
|
gint nMonitor;
|
|
GdkScreen *pScreen;
|
|
GdkRectangle aRect;
|
|
- pScreen = getScreenMonitorFromIdx (mpDisplay, nScreen, nMonitor);
|
|
+ pScreen = getScreenMonitorFromIdx (nScreen, nMonitor);
|
|
if (!pScreen)
|
|
return Rectangle();
|
|
gdk_screen_get_monitor_geometry (pScreen, nMonitor, &aRect);
|
|
@@ -212,7 +261,7 @@ rtl::OUString GtkSalSystem::GetDisplayScreenName(unsigned int nScreen)
|
|
gchar *pStr;
|
|
gint nMonitor;
|
|
GdkScreen *pScreen;
|
|
- pScreen = getScreenMonitorFromIdx (mpDisplay, nScreen, nMonitor);
|
|
+ pScreen = getScreenMonitorFromIdx (nScreen, nMonitor);
|
|
if (!pScreen)
|
|
return rtl::OUString();
|
|
|
|
diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx
|
|
index 28776f1..eb77e75 100644
|
|
--- a/vcl/unx/gtk/window/gtkframe.cxx
|
|
+++ b/vcl/unx/gtk/window/gtkframe.cxx
|
|
@@ -593,7 +593,7 @@ void GtkSalFrame::updateScreenNumber()
|
|
int nScreen = 0;
|
|
GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow );
|
|
if( pScreen )
|
|
- nScreen = GtkSalSystem::getScreenMonitorIdx( getGdkDisplay(), pScreen, maGeometry.nX, maGeometry.nY );
|
|
+ nScreen = getDisplay()->getSystem()->getScreenMonitorIdx( pScreen, maGeometry.nX, maGeometry.nY );
|
|
maGeometry.nDisplayScreenNumber = nScreen;
|
|
}
|
|
|
|
@@ -1862,7 +1862,7 @@ void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSiz
|
|
|
|
gint nMonitor;
|
|
GdkScreen *pScreen = NULL;
|
|
- pScreen = GtkSalSystem::getScreenMonitorFromIdx( getGdkDisplay(), nNewScreen, nMonitor );
|
|
+ pScreen = getDisplay()->getSystem()->getScreenMonitorFromIdx( nNewScreen, nMonitor );
|
|
|
|
// Heavy lifting, need to move screen ...
|
|
if( pScreen != gtk_widget_get_screen( m_pWindow ))
|
|
--
|
|
1.7.7.6
|
|
|