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
This commit is contained in:
parent
9dcff96ba9
commit
53e3cd047c
@ -14,9 +14,6 @@
|
||||
|
||||
#include "wx/toplevel.h"
|
||||
|
||||
#include <gtk/gtkversion.h>
|
||||
#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_
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -14,9 +14,6 @@
|
||||
|
||||
#if wxUSE_TASKBARICON
|
||||
|
||||
#include <gtk/gtkversion.h>
|
||||
#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
|
||||
|
@ -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);
|
||||
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;
|
||||
}
|
||||
// WM does not support _NET_REQUEST_FRAME_EXTENTS, overall size may
|
||||
// change when correct frame extents become known.
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user