]> git.saurik.com Git - wxWidgets.git/commitdiff
Avoid calling gtk_window_get_position() from "configure-event" handler, if possible.
authorPaul Cornett <paulcor@bullseye.com>
Sat, 17 Aug 2013 16:25:13 +0000 (16:25 +0000)
committerPaul Cornett <paulcor@bullseye.com>
Sat, 17 Aug 2013 16:25:13 +0000 (16:25 +0000)
This avoids a round trip to the X server, which is expensive over a remote connection.
Closes #15116

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74664 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/toplevel.h
src/gtk/toplevel.cpp

index 8a253bffa9d7520ed524a7516dd0bb818870fa82..9f9374b06b6189b281fcc6f267ac85f57ffc4a26 100644 (file)
@@ -94,6 +94,8 @@ public:
 
     virtual void GTKHandleRealized();
 
 
     virtual void GTKHandleRealized();
 
+    void GTKConfigureEvent(int x, int y);
+
     // do *not* call this to iconize the frame, this is a private function!
     void SetIconizeState(bool iconic);
 
     // do *not* call this to iconize the frame, this is a private function!
     void SetIconizeState(bool iconic);
 
@@ -108,7 +110,11 @@ public:
                   m_gdkDecor;
 
     // size of WM decorations
                   m_gdkDecor;
 
     // size of WM decorations
-    wxSize m_decorSize;
+    struct DecorSize
+    {
+        int left, right, top, bottom;
+    };
+    DecorSize m_decorSize;
 
     // private gtk_timeout_add result for mimicing wxUSER_ATTENTION_INFO and
     // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle.
 
     // private gtk_timeout_add result for mimicing wxUSER_ATTENTION_INFO and
     // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle.
@@ -119,7 +125,7 @@ public:
     // return the size of the window without WM decorations
     void GTKDoGetSize(int *width, int *height) const;
 
     // return the size of the window without WM decorations
     void GTKDoGetSize(int *width, int *height) const;
 
-    void GTKUpdateDecorSize(const wxSize& decorSize);
+    void GTKUpdateDecorSize(const DecorSize& decorSize);
 
 protected:
     // give hints to the Window Manager for how the size
 
 protected:
     // give hints to the Window Manager for how the size
@@ -145,7 +151,7 @@ protected:
 
 private:
     void Init();
 
 private:
     void Init();
-    wxSize& GetCachedDecorSize();
+    DecorSize& GetCachedDecorSize();
 
     // size hint increments
     int m_incWidth, m_incHeight;
 
     // size hint increments
     int m_incWidth, m_incHeight;
index 623881ca8a089f79ccce94a5516042b2b9ae63e4..3c7d3038e4d19e99e102a1b0acf4db3cc98cba5b 100644 (file)
@@ -71,11 +71,15 @@ static wxTopLevelWindowGTK *g_lastActiveFrame = NULL;
 // send any activate events at all
 static int g_sendActivateEvent = -1;
 
 // send any activate events at all
 static int g_sendActivateEvent = -1;
 
+#ifdef GDK_WINDOWING_X11
 // Whether _NET_REQUEST_FRAME_EXTENTS support is working
 static enum {
     RFE_STATUS_UNKNOWN, RFE_STATUS_WORKING, RFE_STATUS_BROKEN
 } gs_requestFrameExtentsStatus;
 
 // Whether _NET_REQUEST_FRAME_EXTENTS support is working
 static enum {
     RFE_STATUS_UNKNOWN, RFE_STATUS_WORKING, RFE_STATUS_BROKEN
 } gs_requestFrameExtentsStatus;
 
+static bool gs_decorCacheValid;
+#endif
+
 //-----------------------------------------------------------------------------
 // RequestUserAttention related functions
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // RequestUserAttention related functions
 //-----------------------------------------------------------------------------
@@ -257,7 +261,8 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
         GtkAllocation a;
         gtk_widget_get_allocation(win->m_widget, &a);
         wxSize size(a.width, a.height);
         GtkAllocation a;
         gtk_widget_get_allocation(win->m_widget, &a);
         wxSize size(a.width, a.height);
-        size += win->m_decorSize;
+        size.x += win->m_decorSize.left + win->m_decorSize.right;
+        size.y += win->m_decorSize.top + win->m_decorSize.bottom;
         win->m_width  = size.x;
         win->m_height = size.y;
 
         win->m_width  = size.x;
         win->m_height = size.y;
 
@@ -297,24 +302,36 @@ gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget),
 
 extern "C" {
 static gboolean
 
 extern "C" {
 static gboolean
-gtk_frame_configure_callback( GtkWidget* widget,
-                              GdkEventConfigure *WXUNUSED(event),
+gtk_frame_configure_callback( GtkWidget*,
+                              GdkEventConfigure* gdk_event,
                               wxTopLevelWindowGTK *win )
 {
                               wxTopLevelWindowGTK *win )
 {
-    if (!win->IsShown())
-        return FALSE;
+    win->GTKConfigureEvent(gdk_event->x, gdk_event->y);
+    return false;
+}
+}
 
 
+void wxTopLevelWindowGTK::GTKConfigureEvent(int x, int y)
+{
     wxPoint point;
     wxPoint point;
-    gtk_window_get_position((GtkWindow*)widget, &point.x, &point.y);
-
-    win->m_x = point.x;
-    win->m_y = point.y;
-    wxMoveEvent mevent(point, win->GetId());
-    mevent.SetEventObject( win );
-    win->HandleWindowEvent( mevent );
+#ifdef GDK_WINDOWING_X11
+    if (gs_decorCacheValid)
+    {
+        const DecorSize& decorSize = GetCachedDecorSize();
+        point.x = x - decorSize.left;
+        point.y = y - decorSize.top;
+    }
+    else
+#endif
+    {
+        gtk_window_get_position(GTK_WINDOW(m_widget), &point.x, &point.y);
+    }
 
 
-    return FALSE;
-}
+    m_x = point.x;
+    m_y = point.y;
+    wxMoveEvent event(point, GetId());
+    event.SetEventObject(this);
+    HandleWindowEvent(event);
 }
 
 //-----------------------------------------------------------------------------
 }
 
 //-----------------------------------------------------------------------------
@@ -478,10 +495,9 @@ static gboolean property_notify_event(
             win->m_netFrameExtentsTimerId = 0;
         }
 
             win->m_netFrameExtentsTimerId = 0;
         }
 
-        wxSize decorSize = win->m_decorSize;
-        int left, right, top, bottom;
-        if (wxGetFrameExtents(event->window, &left, &right, &top, &bottom))
-            decorSize.Set(left + right, top + bottom);
+        wxTopLevelWindowGTK::DecorSize decorSize = win->m_decorSize;
+        gs_decorCacheValid = wxGetFrameExtents(event->window,
+            &decorSize.left, &decorSize.right, &decorSize.top, &decorSize.bottom);
 
         win->GTKUpdateDecorSize(decorSize);
     }
 
         win->GTKUpdateDecorSize(decorSize);
     }
@@ -497,10 +513,9 @@ static gboolean request_frame_extents_timeout(void* data)
     gdk_threads_enter();
     wxTopLevelWindowGTK* win = static_cast<wxTopLevelWindowGTK*>(data);
     win->m_netFrameExtentsTimerId = 0;
     gdk_threads_enter();
     wxTopLevelWindowGTK* win = static_cast<wxTopLevelWindowGTK*>(data);
     win->m_netFrameExtentsTimerId = 0;
-    wxSize decorSize = win->m_decorSize;
-    int left, right, top, bottom;
-    if (wxGetFrameExtents(gtk_widget_get_window(win->m_widget), &left, &right, &top, &bottom))
-        decorSize.Set(left + right, top + bottom);
+    wxTopLevelWindowGTK::DecorSize decorSize = win->m_decorSize;
+    wxGetFrameExtents(gtk_widget_get_window(win->m_widget),
+        &decorSize.left, &decorSize.right, &decorSize.top, &decorSize.bottom);
     win->GTKUpdateDecorSize(decorSize);
     gdk_threads_leave();
     return false;
     win->GTKUpdateDecorSize(decorSize);
     gdk_threads_leave();
     return false;
@@ -526,6 +541,7 @@ void wxTopLevelWindowGTK::Init()
     m_updateDecorSize = true;
     m_netFrameExtentsTimerId = 0;
     m_incWidth = m_incHeight = 0;
     m_updateDecorSize = true;
     m_netFrameExtentsTimerId = 0;
     m_incWidth = m_incHeight = 0;
+    memset(&m_decorSize, 0, sizeof(m_decorSize));
 
     m_urgency_hint = -2;
 }
 
     m_urgency_hint = -2;
 }
@@ -1036,7 +1052,8 @@ void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXU
 void wxTopLevelWindowGTK::GTKDoGetSize(int *width, int *height) const
 {
     wxSize size(m_width, m_height);
 void wxTopLevelWindowGTK::GTKDoGetSize(int *width, int *height) const
 {
     wxSize size(m_width, m_height);
-    size -= m_decorSize;
+    size.x -= m_decorSize.left + m_decorSize.right;
+    size.y -= m_decorSize.top + m_decorSize.bottom;
     if (size.x < 0) size.x = 0;
     if (size.y < 0) size.y = 0;
 #if wxUSE_LIBHILDON2
     if (size.x < 0) size.x = 0;
     if (size.y < 0) size.y = 0;
 #if wxUSE_LIBHILDON2
@@ -1160,19 +1177,21 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
     hints.min_height = 1;
     hints.max_width = INT_MAX;
     hints.max_height = INT_MAX;
     hints.min_height = 1;
     hints.max_width = INT_MAX;
     hints.max_height = INT_MAX;
-    if (minSize.x > m_decorSize.x)
-        hints.min_width = minSize.x - m_decorSize.x;
-    if (minSize.y > m_decorSize.y)
-        hints.min_height = minSize.y - m_decorSize.y;
+    const int decorSize_x = m_decorSize.left + m_decorSize.right;
+    const int decorSize_y = m_decorSize.top + m_decorSize.bottom;
+    if (minSize.x > decorSize_x)
+        hints.min_width = minSize.x - decorSize_x;
+    if (minSize.y > decorSize_y)
+        hints.min_height = minSize.y - decorSize_y;
     if (maxSize.x > 0)
     {
     if (maxSize.x > 0)
     {
-        hints.max_width = maxSize.x - m_decorSize.x;
+        hints.max_width = maxSize.x - decorSize_x;
         if (hints.max_width < hints.min_width)
             hints.max_width = hints.min_width;
     }
     if (maxSize.y > 0)
     {
         if (hints.max_width < hints.min_width)
             hints.max_width = hints.min_width;
     }
     if (maxSize.y > 0)
     {
-        hints.max_height = maxSize.y - m_decorSize.y;
+        hints.max_height = maxSize.y - decorSize_y;
         if (hints.max_height < hints.min_height)
             hints.max_height = hints.min_height;
     }
         if (hints.max_height < hints.min_height)
             hints.max_height = hints.min_height;
     }
@@ -1187,14 +1206,16 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
 }
 
 #ifdef GDK_WINDOWING_X11
 }
 
 #ifdef GDK_WINDOWING_X11
-void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
+void wxTopLevelWindowGTK::GTKUpdateDecorSize(const DecorSize& decorSize)
 {
     if (!IsMaximized() && !IsFullScreen())
         GetCachedDecorSize() = decorSize;
 {
     if (!IsMaximized() && !IsFullScreen())
         GetCachedDecorSize() = decorSize;
-    if (m_updateDecorSize && m_decorSize != decorSize)
+    if (m_updateDecorSize && memcmp(&m_decorSize, &decorSize, sizeof(DecorSize)))
     {
         m_useCachedClientSize = false;
     {
         m_useCachedClientSize = false;
-        const wxSize diff = decorSize - m_decorSize;
+        const wxSize diff(
+            decorSize.left - m_decorSize.left + decorSize.right - m_decorSize.right,
+            decorSize.top - m_decorSize.top + decorSize.bottom - m_decorSize.bottom);
         m_decorSize = decorSize;
         bool resized = false;
         if (m_minWidth > 0 || m_minHeight > 0 || m_maxWidth > 0 || m_maxHeight > 0)
         m_decorSize = decorSize;
         bool resized = false;
         if (m_minWidth > 0 || m_minHeight > 0 || m_maxWidth > 0 || m_maxHeight > 0)
@@ -1208,7 +1229,8 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
             int w, h;
             GTKDoGetSize(&w, &h);
             // but not if size would be less than minimum, it won't take effect
             int w, h;
             GTKDoGetSize(&w, &h);
             // but not if size would be less than minimum, it won't take effect
-            if (w >= m_minWidth - decorSize.x && h >= m_minHeight - decorSize.y )
+            if (w >= m_minWidth - (decorSize.left + decorSize.right) &&
+                h >= m_minHeight - (decorSize.top + decorSize.bottom))
             {
                 gtk_window_resize(GTK_WINDOW(m_widget), w, h);
                 resized = true;
             {
                 gtk_window_resize(GTK_WINDOW(m_widget), w, h);
                 resized = true;
@@ -1243,9 +1265,9 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
 }
 #endif // GDK_WINDOWING_X11
 
 }
 #endif // GDK_WINDOWING_X11
 
-wxSize& wxTopLevelWindowGTK::GetCachedDecorSize()
+wxTopLevelWindowGTK::DecorSize& wxTopLevelWindowGTK::GetCachedDecorSize()
 {
 {
-    static wxSize size[8];
+    static DecorSize size[8];
 
     int index = 0;
     // title bar
 
     int index = 0;
     // title bar