X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/01a49fd4c45feebb15de2783fce97d6ed48b09e3..ff7dbb27d495cc5e7369016aaa1d7449968368aa:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 6018aa3489..2b1d991e42 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -31,7 +31,6 @@ #include "wx/tooltip.h" #include "wx/caret.h" #include "wx/fontutil.h" -#include "wx/scopeguard.h" #include "wx/sysopt.h" #include @@ -43,6 +42,7 @@ using namespace wxGTKImpl; #ifdef GDK_WINDOWING_X11 #include +#include "wx/x11/private/wrapxkb.h" #else typedef guint KeySym; #endif @@ -221,28 +221,6 @@ int g_lastButtonNumber = 0; // the trace mask used for the focus debugging messages #define TRACE_FOCUS wxT("focus") -//----------------------------------------------------------------------------- -// "size_request" of m_widget -//----------------------------------------------------------------------------- - -extern "C" { -static void -wxgtk_window_size_request_callback(GtkWidget * WXUNUSED(widget), - GtkRequisition *requisition, - wxWindow * win) -{ - int w, h; - win->GetSize( &w, &h ); - if (w < 2) - w = 2; - if (h < 2) - h = 2; - - requisition->height = h; - requisition->width = w; -} -} - //----------------------------------------------------------------------------- // "expose_event" of m_wxwindow //----------------------------------------------------------------------------- @@ -746,7 +724,11 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, wxLogTrace(TRACE_KEYS, wxT("\t-> keycode %d"), keycode); +#ifdef HAVE_X11_XKBLIB_H + KeySym keysymNormalized = XkbKeycodeToKeysym(dpy, keycode, 0, 0); +#else KeySym keysymNormalized = XKeycodeToKeysym(dpy, keycode, 0); +#endif // use the normalized, i.e. lower register, keysym if we've // got one @@ -2062,6 +2044,13 @@ void wxWindowGTK::GTKHandleRealized() wxWindow *wxWindowBase::DoFindFocus() { + // For compatibility with wxMSW, pretend that showing a popup menu doesn't + // change the focus and that it remains on the window showing it, even + // though the real focus does change in GTK. + extern wxMenu *wxCurrentPopupMenu; + if ( wxCurrentPopupMenu ) + return wxCurrentPopupMenu->GetInvokingWindow(); + wxWindowGTK *focus = gs_pendingFocus ? gs_pendingFocus : gs_currentFocus; // the cast is necessary when we compile in wxUniversal mode return static_cast(focus); @@ -2077,9 +2066,8 @@ void wxWindowGTK::AddChildGTK(wxWindowGTK* child) child->m_x += pizza->m_scroll_x; child->m_y += pizza->m_scroll_y; - gtk_widget_set_size_request( - child->m_widget, child->m_width, child->m_height); - pizza->put(child->m_widget, child->m_x, child->m_y); + pizza->put(child->m_widget, + child->m_x, child->m_y, child->m_width, child->m_height); } //----------------------------------------------------------------------------- @@ -2494,16 +2482,8 @@ void wxWindowGTK::PostCreation() } #endif // GTK+ >= 2.8 - if ( GTKShouldConnectSizeRequest() ) - { - // This is needed if we want to add our windows into native - // GTK controls, such as the toolbar. With this callback, the - // toolbar gets to know the correct size (the one set by the - // programmer). Sadly, it misbehaves for wxComboBox. - g_signal_connect (m_widget, "size_request", - G_CALLBACK (wxgtk_window_size_request_callback), - this); - } + if (!WX_IS_PIZZA(gtk_widget_get_parent(m_widget)) && !GTK_IS_WINDOW(m_widget)) + gtk_widget_set_size_request(m_widget, m_width, m_height); InheritAttributes(); @@ -2564,16 +2544,47 @@ bool wxWindowGTK::Destroy() return wxWindowBase::Destroy(); } +static GSList* gs_queueResizeList; + +extern "C" { +static gboolean queue_resize(void*) +{ + gdk_threads_enter(); + for (GSList* p = gs_queueResizeList; p; p = p->next) + { + if (p->data) + { + gtk_widget_queue_resize(GTK_WIDGET(p->data)); + g_object_remove_weak_pointer(G_OBJECT(p->data), &p->data); + } + } + g_slist_free(gs_queueResizeList); + gs_queueResizeList = NULL; + gdk_threads_leave(); + return false; +} +} + void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height) { GtkWidget* parent = gtk_widget_get_parent(m_widget); if (WX_IS_PIZZA(parent)) - { - WX_PIZZA(parent)->move(m_widget, x, y); + WX_PIZZA(parent)->move(m_widget, x, y, width, height); + else gtk_widget_set_size_request(m_widget, width, height); + + // With GTK3, gtk_widget_queue_resize() is ignored while a size-allocate + // is in progress. This situation is common in wxWidgets, since + // size-allocate can generate wxSizeEvent and size event handlers often + // call SetSize(), directly or indirectly. Work around this by deferring + // the queue-resize until after size-allocate processing is finished. + if (g_slist_find(gs_queueResizeList, m_widget) == NULL) + { + if (gs_queueResizeList == NULL) + g_idle_add_full(GTK_PRIORITY_RESIZE, queue_resize, NULL, NULL); + gs_queueResizeList = g_slist_prepend(gs_queueResizeList, m_widget); + g_object_add_weak_pointer(G_OBJECT(m_widget), &gs_queueResizeList->data); } - else - gtk_widget_queue_resize(m_widget); } void wxWindowGTK::ConstrainSize() @@ -4178,14 +4189,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) { wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") ); - // For compatibility with other ports, pretend that the window showing the - // menu has focus while the menu is shown. This is needed because the popup - // menu actually steals the focus from the window it's associated it in - // wxGTK unlike, say, wxMSW. - wxWindowGTK* const oldPendingFocus = gs_pendingFocus; - gs_pendingFocus = this; - wxON_BLOCK_EXIT_SET( gs_pendingFocus, oldPendingFocus ); - menu->UpdateUI(); wxPoint pos;