[libreoffice] Resolves: rhbz#809019 Impress thinks a machine with 2 monitors in clone mode is multihead

David Tardon dtardon at fedoraproject.org
Fri May 11 10:41:35 UTC 2012


commit 6cb277798e17532ef4b7b4cbb6bfec293a6dc7e8
Author: David Tardon <dtardon at redhat.com>
Date:   Fri May 11 12:13:23 2012 +0200

    Resolves: rhbz#809019 Impress thinks a machine with 2 monitors in clone mode is multihead

 ...hbz-809019-count-mirrored-monitors-as-one.patch |  269 ++++++++++++++++++++
 libreoffice.spec                                   |    4 +
 2 files changed, 273 insertions(+), 0 deletions(-)
---
diff --git a/0001-rhbz-809019-count-mirrored-monitors-as-one.patch b/0001-rhbz-809019-count-mirrored-monitors-as-one.patch
new file mode 100644
index 0000000..b0a8f38
--- /dev/null
+++ b/0001-rhbz-809019-count-mirrored-monitors-as-one.patch
@@ -0,0 +1,269 @@
+From 83dd316f42bcc959a533e6be2ba24bbc37417a0a Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon at 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
+@@ -36,7 +36,11 @@
+ 
+ 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 +60,11 @@ public:
+             { 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
+
diff --git a/libreoffice.spec b/libreoffice.spec
index e0d4f27..c2e2b2a 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -148,6 +148,7 @@ Patch34: 0001-Resolves-rhbz-805743-a11y-call-doShow-after-we-have-.patch
 Patch35: 0001-do-not-prepend-n-twice-it-confuses-KFileDialog-rhbz-.patch
 Patch36: 0001-incrementing-index-twice-in-one-run-seems-wrong.patch
 Patch37: 0001-fdo-49365-correctly-map-monitor-index-back-to-screen.patch
+Patch38: 0001-rhbz-809019-count-mirrored-monitors-as-one.patch
 
 %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 %define instdir %{_libdir}
@@ -1012,6 +1013,7 @@ mv -f redhat.soc extras/source/palettes/standard.soc
 %patch35 -p1 -b .do-not-prepend-n-twice-it-confuses-KFileDialog-rhbz-.patch
 %patch36 -p1 -b .rhbz-809019-count-mirrored-monitors-as-one.patch
 %patch37 -p1 -b .incrementing-index-twice-in-one-run-seems-wrong.patch
+%patch38 -p1 -b .rhbz-809019-count-mirrored-monitors-as-one.patch
 
 # TODO: check this
 # these are horribly incomplete--empty translations and copied english
@@ -2303,6 +2305,8 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
 - Resolves: rhbz#820439 KDE export dialog broken for most formats
 - Resolves: fdo#49365 Libreoffice fails to start on second screen with
   gtk vcl plugin
+- Resolves: rhbz#809019 Impress thinks a machine with 2 monitors in
+  clone mode is multihead
 
 * Wed May 09 2012 Caolán McNamara <caolanm at redhat.com> - 3.5.3.2-3
 - Resolves: rhbz#805743 a11y crash in impress/draw


More information about the scm-commits mailing list