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:
@@ -14,9 +14,6 @@
|
|||||||
|
|
||||||
#include "wx/toplevel.h"
|
#include "wx/toplevel.h"
|
||||||
|
|
||||||
#include <gtk/gtkversion.h>
|
|
||||||
#if GTK_CHECK_VERSION(2, 1, 0)
|
|
||||||
|
|
||||||
class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxTopLevelWindow
|
class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxTopLevelWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -25,8 +22,6 @@ public:
|
|||||||
// Returns true if SYSTRAY protocol is supported by the desktop
|
// Returns true if SYSTRAY protocol is supported by the desktop
|
||||||
bool IsProtocolSupported();
|
bool IsProtocolSupported();
|
||||||
|
|
||||||
virtual bool IsDecorCacheable() const;
|
|
||||||
|
|
||||||
wxEvtHandler *m_invokingWindow;
|
wxEvtHandler *m_invokingWindow;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -35,5 +30,4 @@ protected:
|
|||||||
#endif // wxUSE_MENUS_NATIVE
|
#endif // wxUSE_MENUS_NATIVE
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GTK_CHECK_VERSION(2, 1, 0)
|
|
||||||
#endif // _WX_GTK_TASKBARPRIV_H_
|
#endif // _WX_GTK_TASKBARPRIV_H_
|
||||||
|
@@ -94,6 +94,8 @@ public:
|
|||||||
|
|
||||||
GtkWidget *m_mainWidget;
|
GtkWidget *m_mainWidget;
|
||||||
|
|
||||||
|
bool m_deferShow;
|
||||||
|
|
||||||
bool m_fsIsShowing; /* full screen */
|
bool m_fsIsShowing; /* full screen */
|
||||||
int m_fsSaveGdkFunc, m_fsSaveGdkDecor;
|
int m_fsSaveGdkFunc, m_fsSaveGdkDecor;
|
||||||
wxRect m_fsSaveFrame;
|
wxRect m_fsSaveFrame;
|
||||||
@@ -112,9 +114,6 @@ public:
|
|||||||
// return the size of the window without WM decorations
|
// return the size of the window without WM decorations
|
||||||
void GTKDoGetSize(int *width, int *height) const;
|
void GTKDoGetSize(int *width, int *height) const;
|
||||||
|
|
||||||
// whether frame extents are accurate
|
|
||||||
virtual bool IsDecorCacheable() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// give hints to the Window Manager for how the size
|
// give hints to the Window Manager for how the size
|
||||||
// of the TLW can be changed by dragging
|
// 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)
|
if (style & wxRESIZE_BORDER)
|
||||||
m_gdkFunc = GDK_FUNC_RESIZE;
|
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
|
// don't allow sizing smaller than decorations
|
||||||
GdkGeometry geom;
|
GdkGeometry geom;
|
||||||
geom.min_width = 2 * m_miniEdge;
|
geom.min_width = 2 * m_miniEdge;
|
||||||
|
@@ -14,9 +14,6 @@
|
|||||||
|
|
||||||
#if wxUSE_TASKBARICON
|
#if wxUSE_TASKBARICON
|
||||||
|
|
||||||
#include <gtk/gtkversion.h>
|
|
||||||
#if GTK_CHECK_VERSION(2, 1, 0)
|
|
||||||
|
|
||||||
#include "wx/gtk/taskbarpriv.h"
|
#include "wx/gtk/taskbarpriv.h"
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
@@ -47,6 +44,16 @@ wxTaskBarIconAreaBase::wxTaskBarIconAreaBase()
|
|||||||
wxFRAME_SHAPED,
|
wxFRAME_SHAPED,
|
||||||
wxEmptyString /*eggtray doesn't like setting wmclass*/);
|
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;
|
m_invokingWindow = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,13 +78,6 @@ bool wxTaskBarIconAreaBase::IsProtocolSupported()
|
|||||||
return (bool)s_supported;
|
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
|
// Pop-up menu stuff
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -150,5 +150,4 @@ bool wxTaskBarIconAreaBase::DoPopupMenu( wxMenu *menu, int x, int y )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_MENUS_NATIVE
|
#endif // wxUSE_MENUS_NATIVE
|
||||||
#endif // GTK_CHECK_VERSION(2, 1, 0)
|
|
||||||
#endif // wxUSE_TASKBARICON
|
#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
|
// "size_allocate" from m_wxwindow
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -237,8 +218,7 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
|
|||||||
|
|
||||||
wxSize size(win->m_widget->allocation.width,
|
wxSize size(win->m_widget->allocation.width,
|
||||||
win->m_widget->allocation.height);
|
win->m_widget->allocation.height);
|
||||||
if (!win->IsFullScreen())
|
size += win->m_decorSize;
|
||||||
size += win->m_decorSize;
|
|
||||||
win->m_width = size.x;
|
win->m_width = size.x;
|
||||||
win->m_height = size.y;
|
win->m_height = size.y;
|
||||||
|
|
||||||
@@ -356,29 +336,10 @@ gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_frame_map_callback( GtkWidget* widget,
|
gtk_frame_map_callback( GtkWidget*,
|
||||||
GdkEvent * WXUNUSED(event),
|
GdkEvent * WXUNUSED(event),
|
||||||
wxTopLevelWindow *win )
|
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();
|
const bool wasIconized = win->IsIconized();
|
||||||
|
|
||||||
win->SetIconizeState(false);
|
win->SetIconizeState(false);
|
||||||
@@ -424,8 +385,7 @@ static gboolean property_notify_event(
|
|||||||
{
|
{
|
||||||
// Watch for changes to _NET_FRAME_EXTENTS property
|
// Watch for changes to _NET_FRAME_EXTENTS property
|
||||||
static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false);
|
static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false);
|
||||||
if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property &&
|
if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property)
|
||||||
win->IsDecorCacheable() && !win->IsFullScreen())
|
|
||||||
{
|
{
|
||||||
Atom xproperty = gdk_x11_atom_to_xatom_for_display(
|
Atom xproperty = gdk_x11_atom_to_xatom_for_display(
|
||||||
gdk_drawable_get_display(event->window), property);
|
gdk_drawable_get_display(event->window), property);
|
||||||
@@ -447,8 +407,7 @@ static gboolean property_notify_event(
|
|||||||
{
|
{
|
||||||
const wxSize diff = win->m_decorSize - decorSize;
|
const wxSize diff = win->m_decorSize - decorSize;
|
||||||
win->m_decorSize = decorSize;
|
win->m_decorSize = decorSize;
|
||||||
GetDecorSize(win->m_gdkDecor) = decorSize;
|
if (!win->m_deferShow)
|
||||||
if (GTK_WIDGET_VISIBLE(win->m_widget))
|
|
||||||
{
|
{
|
||||||
// adjust overall size to match change in frame extents
|
// adjust overall size to match change in frame extents
|
||||||
win->m_width -= diff.x;
|
win->m_width -= diff.x;
|
||||||
@@ -467,9 +426,10 @@ static gboolean property_notify_event(
|
|||||||
gtk_window_resize(GTK_WINDOW(win->m_widget), w, h);
|
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
|
// gtk_widget_show() was deferred, do it now
|
||||||
|
win->m_deferShow = false;
|
||||||
wxSizeEvent sizeEvent(win->GetSize(), win->GetId());
|
wxSizeEvent sizeEvent(win->GetSize(), win->GetId());
|
||||||
sizeEvent.SetEventObject(win);
|
sizeEvent.SetEventObject(win);
|
||||||
win->HandleWindowEvent(sizeEvent);
|
win->HandleWindowEvent(sizeEvent);
|
||||||
@@ -503,6 +463,7 @@ void wxTopLevelWindowGTK::Init()
|
|||||||
m_themeEnabled = true;
|
m_themeEnabled = true;
|
||||||
m_gdkDecor = m_gdkFunc = 0;
|
m_gdkDecor = m_gdkFunc = 0;
|
||||||
m_grabbed = false;
|
m_grabbed = false;
|
||||||
|
m_deferShow = true;
|
||||||
|
|
||||||
m_urgency_hint = -2;
|
m_urgency_hint = -2;
|
||||||
}
|
}
|
||||||
@@ -697,12 +658,7 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_decorSize = GetDecorSize(m_gdkDecor);
|
gtk_window_set_default_size(GTK_WINDOW(m_widget), m_width, m_height);
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -839,7 +795,9 @@ bool wxTopLevelWindowGTK::Show( bool show )
|
|||||||
{
|
{
|
||||||
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
|
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
|
// Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer
|
||||||
// calling gtk_widget_show() until _NET_FRAME_EXTENTS property
|
// calling gtk_widget_show() until _NET_FRAME_EXTENTS property
|
||||||
@@ -865,32 +823,34 @@ bool wxTopLevelWindowGTK::Show( bool show )
|
|||||||
g_object_unref(child);
|
g_object_unref(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if WM supports _NET_REQUEST_FRAME_EXTENTS
|
m_deferShow =
|
||||||
GdkAtom request_extents =
|
deferShow = gdk_x11_screen_supports_net_wm_hint(
|
||||||
gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false);
|
gdk_drawable_get_screen(m_widget->window),
|
||||||
GdkScreen* screen = gdk_drawable_get_screen(m_widget->window);
|
gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)) != 0;
|
||||||
if (gdk_x11_screen_supports_net_wm_hint(screen, request_extents))
|
}
|
||||||
{
|
if (deferShow)
|
||||||
// send _NET_REQUEST_FRAME_EXTENTS
|
{
|
||||||
XClientMessageEvent xevent;
|
// send _NET_REQUEST_FRAME_EXTENTS
|
||||||
memset(&xevent, 0, sizeof(xevent));
|
XClientMessageEvent xevent;
|
||||||
xevent.type = ClientMessage;
|
memset(&xevent, 0, sizeof(xevent));
|
||||||
xevent.window = gdk_x11_drawable_get_xid(m_widget->window);
|
xevent.type = ClientMessage;
|
||||||
xevent.message_type = gdk_x11_atom_to_xatom_for_display(
|
xevent.window = gdk_x11_drawable_get_xid(m_widget->window);
|
||||||
gdk_drawable_get_display(m_widget->window), request_extents);
|
xevent.message_type = gdk_x11_atom_to_xatom_for_display(
|
||||||
xevent.format = 32;
|
gdk_drawable_get_display(m_widget->window),
|
||||||
Display* display = gdk_x11_drawable_get_xdisplay(m_widget->window);
|
gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false));
|
||||||
XSendEvent(display, DefaultRootWindow(display), false,
|
xevent.format = 32;
|
||||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
Display* display = gdk_x11_drawable_get_xdisplay(m_widget->window);
|
||||||
(XEvent*)&xevent);
|
XSendEvent(display, DefaultRootWindow(display), false,
|
||||||
|
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||||
|
(XEvent*)&xevent);
|
||||||
|
|
||||||
// defer calling gtk_widget_show()
|
// defer calling gtk_widget_show()
|
||||||
m_isShown = true;
|
m_isShown = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// WM does not support _NET_REQUEST_FRAME_EXTENTS, overall size may
|
|
||||||
// change when correct frame extents become known.
|
|
||||||
|
|
||||||
|
if (show && !wasRealized)
|
||||||
|
{
|
||||||
// size_allocate signals occur in reverse order (bottom to top).
|
// size_allocate signals occur in reverse order (bottom to top).
|
||||||
// Things work better if the initial wxSizeEvents are sent (from the
|
// Things work better if the initial wxSizeEvents are sent (from the
|
||||||
// top down), before the initial size_allocate signals occur.
|
// 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
|
void wxTopLevelWindowGTK::GTKDoGetSize(int *width, int *height) const
|
||||||
{
|
{
|
||||||
wxSize size(m_width, m_height);
|
wxSize size(m_width, m_height);
|
||||||
if (!IsFullScreen())
|
size -= m_decorSize;
|
||||||
{
|
if (size.x < 0) size.x = 0;
|
||||||
size -= m_decorSize;
|
if (size.y < 0) size.y = 0;
|
||||||
if (size.x < 0) size.x = 0;
|
|
||||||
if (size.y < 0) size.y = 0;
|
|
||||||
}
|
|
||||||
if (width) *width = size.x;
|
if (width) *width = size.x;
|
||||||
if (height) *height = size.y;
|
if (height) *height = size.y;
|
||||||
}
|
}
|
||||||
@@ -1044,11 +1001,6 @@ void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH,
|
|||||||
(GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask);
|
(GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTopLevelWindowGTK::IsDecorCacheable() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxTopLevelWindowGTK::OnInternalIdle()
|
void wxTopLevelWindowGTK::OnInternalIdle()
|
||||||
{
|
{
|
||||||
// set the focus if not done yet and if we can already do it
|
// set the focus if not done yet and if we can already do it
|
||||||
|
Reference in New Issue
Block a user