}
}
+// ----------------------------------------------------------------------------
+// "key_press_event"
+// ----------------------------------------------------------------------------
+
+extern "C" {
+static gboolean
+wxgtk_tlw_key_press_event(GtkWidget *widget, GdkEventKey *event)
+{
+ GtkWindow* const window = GTK_WINDOW(widget);
+
+ // By default GTK+ checks for the menu accelerators in this (top level)
+ // window first and then propagates the event to the currently focused
+ // child from where it bubbles up the window parent chain. In wxWidgets,
+ // however, we want the child window to have the event first but still
+ // handle it as an accelerator if it's not processed there, so we need to
+ // customize this by reversing the order of the steps done in the standard
+ // GTK+ gtk_window_key_press_event() handler.
+
+ if ( gtk_window_propagate_key_event(window, event) )
+ return TRUE;
+
+ if ( gtk_window_activate_key(window, event) )
+ return TRUE;
+
+ if (GTK_WIDGET_GET_CLASS(widget)->key_press_event(widget, event))
+ return TRUE;
+
+ return FALSE;
+}
+}
+
//-----------------------------------------------------------------------------
// "size_allocate" from m_wxwindow
//-----------------------------------------------------------------------------
static void
size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
{
- if (win->m_oldClientWidth != alloc->width ||
- win->m_oldClientHeight != alloc->height)
+ win->m_useCachedClientSize = true;
+ if (win->m_clientWidth != alloc->width ||
+ win->m_clientHeight != alloc->height)
{
- win->m_oldClientWidth = alloc->width;
- win->m_oldClientHeight = alloc->height;
+ win->m_clientWidth = alloc->width;
+ win->m_clientHeight = alloc->height;
GtkAllocation a;
gtk_widget_get_allocation(win->m_widget, &a);
GdkEventConfigure *WXUNUSED(event),
wxTopLevelWindowGTK *win )
{
- if (!win->m_hasVMT || !win->IsShown())
+ if (!win->IsShown())
return FALSE;
wxPoint point;
// tlw that was "rolled up" with some WMs.
// Queue a resize rather than sending size event directly to allow
// children to be made visible first.
- win->m_oldClientWidth = 0;
+ win->m_useCachedClientSize = false;
+ win->m_clientWidth = 0;
gtk_widget_queue_resize(win->m_wxwindow);
}
// it is possible for m_isShown to be false here, see bug #9909
win->GetEventHandler()->ProcessEvent(eventShow);
}
- {
- // restore focus-on-map setting in case ShowWithoutActivating() was called
- gtk_window_set_focus_on_map(GTK_WINDOW(win->m_widget), true);
- }
+ // restore focus-on-map setting in case ShowWithoutActivating() was called
+ gtk_window_set_focus_on_map(GTK_WINDOW(win->m_widget), true);
return false;
}
// if maximized bit changed and it is now set
if (event->changed_mask & event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
{
- wxMaximizeEvent event(win->GetId());
- event.SetEventObject(win);
- win->HandleWindowEvent(event);
+ wxMaximizeEvent evt(win->GetId());
+ evt.SetEventObject(win);
+ win->HandleWindowEvent(evt);
}
+ if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
+ win->m_fsIsShowing = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0;
+
return false;
}
}
#endif
}
+#ifdef GDK_WINDOWING_X11
//-----------------------------------------------------------------------------
// "property_notify_event" from m_widget
//-----------------------------------------------------------------------------
return false;
}
}
+#endif // GDK_WINDOWING_X11
// ----------------------------------------------------------------------------
// wxTopLevelWindowGTK creation
G_CALLBACK (gtk_frame_delete_callback), this);
// m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow)
- m_mainWidget = gtk_vbox_new(false, 0);
+ m_mainWidget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_show( m_mainWidget );
gtk_widget_set_can_focus(m_mainWidget, false);
gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
// m_wxwindow is the client area
m_wxwindow = wxPizza::New();
gtk_widget_show( m_wxwindow );
- gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
+ gtk_box_pack_start(GTK_BOX(m_mainWidget), m_wxwindow, true, true, 0);
// we donm't allow the frame to get the focus as otherwise
// the frame will grab it at arbitrary focus changes
g_signal_connect_after (m_widget, "focus_out_event",
G_CALLBACK (gtk_frame_focus_out_callback), this);
- gtk_widget_add_events(m_widget, GDK_PROPERTY_CHANGE_MASK);
- g_signal_connect(m_widget, "property_notify_event",
- G_CALLBACK(property_notify_event), this);
+ // We need to customize the default GTK+ logic for key processing to make
+ // it conforming to wxWidgets event processing order.
+ g_signal_connect (m_widget, "key_press_event",
+ G_CALLBACK (wxgtk_tlw_key_press_event), NULL);
+
+#ifdef GDK_WINDOWING_X11
+#ifdef __WXGTK3__
+ if (GDK_IS_X11_SCREEN(gtk_window_get_screen(GTK_WINDOW(m_widget))))
+#endif
+ {
+ gtk_widget_add_events(m_widget, GDK_PROPERTY_CHANGE_MASK);
+ g_signal_connect(m_widget, "property_notify_event",
+ G_CALLBACK(property_notify_event), this);
+ }
+#endif // GDK_WINDOWING_X11
// translate wx decorations styles into Motif WM hints (they are recognized
// by other WMs as well)
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
+#ifdef GDK_WINDOWING_X11
bool deferShow = show && !m_isShown && m_deferShow;
if (deferShow)
{
- deferShow = gs_requestFrameExtentsStatus != 2 &&
- m_deferShowAllowed && !gtk_widget_get_realized(m_widget);
- if (deferShow)
- {
- deferShow = g_signal_handler_find(m_widget,
+ deferShow = m_deferShowAllowed && gs_requestFrameExtentsStatus != 2 &&
+ !gtk_widget_get_realized(m_widget) &&
+ 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) != 0;
- }
- GdkScreen* screen = NULL;
+ 0, NULL, NULL, this);
if (deferShow)
{
-#ifdef GDK_WINDOWING_X11
- screen = gtk_widget_get_screen(m_widget);
+ GdkScreen* screen = gtk_widget_get_screen(m_widget);
GdkAtom atom = gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false);
deferShow = gdk_x11_screen_supports_net_wm_hint(screen, atom) != 0;
-#else
- deferShow = false;
-#endif
+
// If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes
// to m_decorSize, it breaks saving/restoring window size with
// GetSize()/SetSize() because it makes window bigger between each
gtk_widget_set_allocation(m_widget, &alloc);
}
-#ifdef GDK_WINDOWING_X11
// send _NET_REQUEST_FRAME_EXTENTS
XClientMessageEvent xevent;
memset(&xevent, 0, sizeof(xevent));
XSendEvent(display, DefaultRootWindow(display), false,
SubstructureNotifyMask | SubstructureRedirectMask,
(XEvent*)&xevent);
-#endif // GDK_WINDOWING_X11
if (gs_requestFrameExtentsStatus == 0)
{
m_isShown = true;
return true;
}
+#endif // GDK_WINDOWING_X11
if (show && !gtk_widget_get_realized(m_widget))
{
{
if (!m_isShown)
{
- gtk_window_set_focus_on_map(GTK_WINDOW(m_widget), false);
-
+ gtk_window_set_focus_on_map(GTK_WINDOW(m_widget), false);
Show(true);
}
}
{
wxCHECK_RET( m_widget, wxT("invalid frame") );
- m_deferShowAllowed = true;
-
// deal with the position first
int old_x = m_x;
int old_y = m_y;
if (m_height < 1) m_height = 1;
if (m_width != oldSize.x || m_height != oldSize.y)
{
+ m_deferShowAllowed = true;
+ m_useCachedClientSize = false;
+
int w, h;
GTKDoGetSize(&w, &h);
gtk_window_resize(GTK_WINDOW(m_widget), w, h);
- GetClientSize(&m_oldClientWidth, &m_oldClientHeight);
+ DoGetClientSize(&m_clientWidth, &m_clientHeight);
wxSizeEvent event(GetSize(), GetId());
event.SetEventObject(this);
HandleWindowEvent(event);
if ( height )
*height = 0;
}
+ else if (m_useCachedClientSize)
+ base_type::DoGetClientSize(width, height);
else
{
GTKDoGetSize(width, height);
(GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask);
}
+#ifdef GDK_WINDOWING_X11
void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
{
if (!IsMaximized() && !IsFullScreen())
GetCachedDecorSize() = decorSize;
if (m_updateDecorSize && m_decorSize != decorSize)
{
+ m_useCachedClientSize = false;
const wxSize diff = decorSize - m_decorSize;
m_decorSize = decorSize;
bool resized = false;
m_height += diff.y;
if (m_width < 1) m_width = 1;
if (m_height < 1) m_height = 1;
- m_oldClientWidth = 0;
+ m_clientWidth = 0;
gtk_widget_queue_resize(m_wxwindow);
}
}
{
// gtk_widget_show() was deferred, do it now
m_deferShow = false;
- GetClientSize(&m_oldClientWidth, &m_oldClientHeight);
+ DoGetClientSize(&m_clientWidth, &m_clientHeight);
wxSizeEvent sizeEvent(GetSize(), GetId());
sizeEvent.SetEventObject(this);
HandleWindowEvent(sizeEvent);
HandleWindowEvent(showEvent);
}
}
+#endif // GDK_WINDOWING_X11
wxSize& wxTopLevelWindowGTK::GetCachedDecorSize()
{