From 53e3cd047cb9d01952af76779e89e444915e86c6 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Tue, 4 Dec 2007 17:26:57 +0000 Subject: [PATCH] Only account for WM frame extents in tlw size if WM supports _NET_FRAME_EXTENTS. Extents cache no longer needed. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50467 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/taskbarpriv.h | 6 -- include/wx/gtk/toplevel.h | 5 +- src/gtk/minifram.cpp | 4 -- src/gtk/taskbar.cpp | 21 +++--- src/gtk/toplevel.cpp | 130 +++++++++++------------------------ 5 files changed, 53 insertions(+), 113 deletions(-) diff --git a/include/wx/gtk/taskbarpriv.h b/include/wx/gtk/taskbarpriv.h index 58a4381952..f92b680ee1 100644 --- a/include/wx/gtk/taskbarpriv.h +++ b/include/wx/gtk/taskbarpriv.h @@ -14,9 +14,6 @@ #include "wx/toplevel.h" -#include -#if GTK_CHECK_VERSION(2, 1, 0) - class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxTopLevelWindow { public: @@ -25,8 +22,6 @@ public: // Returns true if SYSTRAY protocol is supported by the desktop bool IsProtocolSupported(); - virtual bool IsDecorCacheable() const; - wxEvtHandler *m_invokingWindow; protected: @@ -35,5 +30,4 @@ protected: #endif // wxUSE_MENUS_NATIVE }; -#endif // GTK_CHECK_VERSION(2, 1, 0) #endif // _WX_GTK_TASKBARPRIV_H_ diff --git a/include/wx/gtk/toplevel.h b/include/wx/gtk/toplevel.h index 3d64548573..dcf60a8c7e 100644 --- a/include/wx/gtk/toplevel.h +++ b/include/wx/gtk/toplevel.h @@ -94,6 +94,8 @@ public: GtkWidget *m_mainWidget; + bool m_deferShow; + bool m_fsIsShowing; /* full screen */ int m_fsSaveGdkFunc, m_fsSaveGdkDecor; wxRect m_fsSaveFrame; @@ -112,9 +114,6 @@ public: // return the size of the window without WM decorations void GTKDoGetSize(int *width, int *height) const; - // whether frame extents are accurate - virtual bool IsDecorCacheable() const; - protected: // give hints to the Window Manager for how the size // of the TLW can be changed by dragging diff --git a/src/gtk/minifram.cpp b/src/gtk/minifram.cpp index 9febe6584f..ed003a902c 100644 --- a/src/gtk/minifram.cpp +++ b/src/gtk/minifram.cpp @@ -347,10 +347,6 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title if (style & wxRESIZE_BORDER) m_gdkFunc = GDK_FUNC_RESIZE; - // need to reset default size after changing m_gdkDecor - gtk_window_set_default_size(GTK_WINDOW(m_widget), m_width, m_height); - m_decorSize.Set(0, 0); - // don't allow sizing smaller than decorations GdkGeometry geom; geom.min_width = 2 * m_miniEdge; diff --git a/src/gtk/taskbar.cpp b/src/gtk/taskbar.cpp index 4bb7f2dcf2..86e5433c6b 100644 --- a/src/gtk/taskbar.cpp +++ b/src/gtk/taskbar.cpp @@ -14,9 +14,6 @@ #if wxUSE_TASKBARICON -#include -#if GTK_CHECK_VERSION(2, 1, 0) - #include "wx/gtk/taskbarpriv.h" #ifndef WX_PRECOMP @@ -47,6 +44,16 @@ wxTaskBarIconAreaBase::wxTaskBarIconAreaBase() wxFRAME_SHAPED, wxEmptyString /*eggtray doesn't like setting wmclass*/); + // WM frame extents are not useful for wxTaskBarIcon + m_deferShow = false; + gulong handler_id = g_signal_handler_find( + m_widget, + GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), + g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET), + 0, NULL, NULL, this); + if (handler_id != 0) + g_signal_handler_disconnect(m_widget, handler_id); + m_invokingWindow = NULL; } @@ -71,13 +78,6 @@ bool wxTaskBarIconAreaBase::IsProtocolSupported() return (bool)s_supported; } -bool wxTaskBarIconAreaBase::IsDecorCacheable() const -{ - // Apparently, WM frame extents extend to full width of screen when window - // is in the tray. Don't cache, it's not useful for other windows. - return false; -} - //----------------------------------------------------------------------------- // Pop-up menu stuff //----------------------------------------------------------------------------- @@ -150,5 +150,4 @@ bool wxTaskBarIconAreaBase::DoPopupMenu( wxMenu *menu, int x, int y ) } #endif // wxUSE_MENUS_NATIVE -#endif // GTK_CHECK_VERSION(2, 1, 0) #endif // wxUSE_TASKBARICON diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index bde85936ac..4bcfa18638 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -202,25 +202,6 @@ gboolean gtk_frame_focus_out_callback(GtkWidget * WXUNUSED(widget), } } -//----------------------------------------------------------------------------- - -// Get cached size of WM decorations for given GdkWMDecoration. -static wxSize& GetDecorSize(int decor) -{ - // In testing, only the title bar and GDK_DECOR_BORDER made a difference. - // 4 possible combinations of title bar and border - static wxSize size[4]; - - int index = 0; - // title bar - if (decor & (GDK_DECOR_MENU | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE | GDK_DECOR_TITLE)) - index = 1; - // border - if (decor & GDK_DECOR_BORDER) - index |= 2; - return size[index]; -} - //----------------------------------------------------------------------------- // "size_allocate" from m_wxwindow //----------------------------------------------------------------------------- @@ -237,8 +218,7 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win) wxSize size(win->m_widget->allocation.width, win->m_widget->allocation.height); - if (!win->IsFullScreen()) - size += win->m_decorSize; + size += win->m_decorSize; win->m_width = size.x; win->m_height = size.y; @@ -356,29 +336,10 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget), extern "C" { static gboolean -gtk_frame_map_callback( GtkWidget* widget, +gtk_frame_map_callback( GtkWidget*, GdkEvent * WXUNUSED(event), wxTopLevelWindow *win ) { - // Calculate size of WM decorations. - // Done here in case WM does not support the _NET_FRAME_EXTENTS property. - if (win->IsDecorCacheable() && !win->IsFullScreen()) - { - GdkRectangle rect; - gdk_window_get_frame_extents(widget->window, &rect); - int w, h; - gdk_drawable_get_size(widget->window, &w, &h); - const wxSize decorSize = wxSize(rect.width - w, rect.height - h); - if (win->m_decorSize != decorSize) - { - // Update window size and frame extents cache - win->m_width = rect.width; - win->m_height = rect.height; - win->m_decorSize = decorSize; - GetDecorSize(win->m_gdkDecor) = decorSize; - } - } - const bool wasIconized = win->IsIconized(); win->SetIconizeState(false); @@ -424,8 +385,7 @@ static gboolean property_notify_event( { // Watch for changes to _NET_FRAME_EXTENTS property static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false); - if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property && - win->IsDecorCacheable() && !win->IsFullScreen()) + if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property) { Atom xproperty = gdk_x11_atom_to_xatom_for_display( gdk_drawable_get_display(event->window), property); @@ -447,8 +407,7 @@ static gboolean property_notify_event( { const wxSize diff = win->m_decorSize - decorSize; win->m_decorSize = decorSize; - GetDecorSize(win->m_gdkDecor) = decorSize; - if (GTK_WIDGET_VISIBLE(win->m_widget)) + if (!win->m_deferShow) { // adjust overall size to match change in frame extents win->m_width -= diff.x; @@ -467,9 +426,10 @@ static gboolean property_notify_event( gtk_window_resize(GTK_WINDOW(win->m_widget), w, h); } } - if (!GTK_WIDGET_VISIBLE(win->m_widget)) + if (win->m_deferShow) { // gtk_widget_show() was deferred, do it now + win->m_deferShow = false; wxSizeEvent sizeEvent(win->GetSize(), win->GetId()); sizeEvent.SetEventObject(win); win->HandleWindowEvent(sizeEvent); @@ -503,6 +463,7 @@ void wxTopLevelWindowGTK::Init() m_themeEnabled = true; m_gdkDecor = m_gdkFunc = 0; m_grabbed = false; + m_deferShow = true; m_urgency_hint = -2; } @@ -697,12 +658,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, } } - m_decorSize = GetDecorSize(m_gdkDecor); - - // m_sizeDecor needs to be set before calling GTKDoGetSize - int w, h; - GTKDoGetSize(&w, &h); - gtk_window_set_default_size(GTK_WINDOW(m_widget), w, h); + gtk_window_set_default_size(GTK_WINDOW(m_widget), m_width, m_height); return true; } @@ -839,7 +795,9 @@ bool wxTopLevelWindowGTK::Show( bool show ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - if (show && !GTK_WIDGET_REALIZED(m_widget)) + const bool wasRealized = GTK_WIDGET_REALIZED(m_widget); + bool deferShow = show && m_deferShow && !wasRealized; + if (deferShow) { // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer // calling gtk_widget_show() until _NET_FRAME_EXTENTS property @@ -865,32 +823,34 @@ bool wxTopLevelWindowGTK::Show( bool show ) g_object_unref(child); } - // if WM supports _NET_REQUEST_FRAME_EXTENTS - GdkAtom request_extents = - gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false); - GdkScreen* screen = gdk_drawable_get_screen(m_widget->window); - if (gdk_x11_screen_supports_net_wm_hint(screen, request_extents)) - { - // send _NET_REQUEST_FRAME_EXTENTS - XClientMessageEvent xevent; - memset(&xevent, 0, sizeof(xevent)); - xevent.type = ClientMessage; - xevent.window = gdk_x11_drawable_get_xid(m_widget->window); - xevent.message_type = gdk_x11_atom_to_xatom_for_display( - gdk_drawable_get_display(m_widget->window), request_extents); - xevent.format = 32; - Display* display = gdk_x11_drawable_get_xdisplay(m_widget->window); - XSendEvent(display, DefaultRootWindow(display), false, - SubstructureNotifyMask | SubstructureRedirectMask, - (XEvent*)&xevent); - - // defer calling gtk_widget_show() - m_isShown = true; - return true; - } - // WM does not support _NET_REQUEST_FRAME_EXTENTS, overall size may - // change when correct frame extents become known. + m_deferShow = + deferShow = gdk_x11_screen_supports_net_wm_hint( + gdk_drawable_get_screen(m_widget->window), + gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)) != 0; + } + if (deferShow) + { + // send _NET_REQUEST_FRAME_EXTENTS + XClientMessageEvent xevent; + memset(&xevent, 0, sizeof(xevent)); + xevent.type = ClientMessage; + xevent.window = gdk_x11_drawable_get_xid(m_widget->window); + xevent.message_type = gdk_x11_atom_to_xatom_for_display( + gdk_drawable_get_display(m_widget->window), + gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)); + xevent.format = 32; + Display* display = gdk_x11_drawable_get_xdisplay(m_widget->window); + XSendEvent(display, DefaultRootWindow(display), false, + SubstructureNotifyMask | SubstructureRedirectMask, + (XEvent*)&xevent); + + // defer calling gtk_widget_show() + m_isShown = true; + return true; + } + if (show && !wasRealized) + { // size_allocate signals occur in reverse order (bottom to top). // Things work better if the initial wxSizeEvents are sent (from the // top down), before the initial size_allocate signals occur. @@ -929,12 +889,9 @@ 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); - if (!IsFullScreen()) - { - size -= m_decorSize; - if (size.x < 0) size.x = 0; - if (size.y < 0) size.y = 0; - } + size -= m_decorSize; + if (size.x < 0) size.x = 0; + if (size.y < 0) size.y = 0; if (width) *width = size.x; if (height) *height = size.y; } @@ -1044,11 +1001,6 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH, (GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask); } -bool wxTopLevelWindowGTK::IsDecorCacheable() const -{ - return true; -} - void wxTopLevelWindowGTK::OnInternalIdle() { // set the focus if not done yet and if we can already do it -- 2.45.2