X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/45eb5249574b0f1f50db5e6a7eb5bba43fd99cb9..8fbdfa4faf61ecc4177d9952d3f3718cf4514ae6:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 2b79315b3d..05a2f829cb 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -486,10 +486,21 @@ static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNU static long map_to_unmodified_wx_keysym( GdkEventKey *event ) { + // VZ: it seems that GDK_KEY_RELEASE event doesn't set event->string + // but only event->keyval which is quite useless to us, so remember + // the last character from GDK_KEY_PRESS and resue it as last resort + // + // NB: should be MT-neutral as always called from main thread only + static struct + { + KeySym keysym; + long keycode; + } s_lastKeyPress = { 0, 0 }; + KeySym keysym = event->keyval; long key_code; - switch (keysym) + switch ( keysym ) { case GDK_Shift_L: case GDK_Shift_R: key_code = WXK_SHIFT; break; @@ -581,16 +592,43 @@ static long map_to_unmodified_wx_keysym( GdkEventKey *event ) case GDK_F11: key_code = WXK_F11; break; case GDK_F12: key_code = WXK_F12; break; default: - if ( (keysym & 0xFF) == keysym ) + { + // do we have the translation? + if ( event->length == 1 ) { - guint upper = gdk_keyval_to_upper( (guint)keysym ); - key_code = upper ? upper : keysym; + keysym = (KeySym)event->string[0]; } - else + else if ( (keysym & 0xFF) != keysym ) + { + // non ASCII key, what to do? + + if ( event->type == GDK_KEY_RELEASE ) + { + // reuse the one from the last keypress if any + if ( keysym == s_lastKeyPress.keysym ) + { + key_code = s_lastKeyPress.keycode; + + // skip "return 0" + break; + } + } + + // ignore this one, we don't know it + return 0; + } + //else: ASCII key, ok + + guint upper = gdk_keyval_to_upper( (guint)keysym ); + key_code = upper ? upper : keysym; + + if ( event->type == GDK_KEY_PRESS ) { - // unknown key code - key_code = 0; + // remember it to be reused below later + s_lastKeyPress.keysym = keysym; + s_lastKeyPress.keycode = key_code; } + } } return key_code; @@ -683,9 +721,6 @@ static long map_to_wx_keysym( GdkEventKey *event ) case GDK_F11: key_code = WXK_F11; break; case GDK_F12: key_code = WXK_F12; break; default: - { - if (event->length == 1) - { if (event->length == 1) { key_code = (unsigned char)*event->string; @@ -694,7 +729,6 @@ static long map_to_wx_keysym( GdkEventKey *event ) { key_code = (guint)keysym; } - } } return key_code; @@ -1299,6 +1333,14 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton event.m_y = (wxCoord)gdk_event->y; AdjustEventButtonState(event); + + // wxListBox actually get mouse events from the item + + if (win->m_isListBox) + { + event.m_x += widget->allocation.x; + event.m_y += widget->allocation.y; + } // Some control don't have their own X window and thus cannot get // any events. @@ -1432,6 +1474,14 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto AdjustEventButtonState(event); + // wxListBox actually get mouse events from the item + + if (win->m_isListBox) + { + event.m_x += widget->allocation.x; + event.m_y += widget->allocation.y; + } + // Some control don't have their own X window and thus cannot get // any events. @@ -1778,7 +1828,14 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED if ( !g_activeFrameLostFocus && g_activeFrame ) { - wxASSERT_MSG( wxGetTopLevelParent(win) == g_activeFrame, wxT("unfocusing window that haven't gained focus properly") ) + // VZ: commenting this out because it does happen (although not easy + // to reproduce, I only see it when using wxMiniFrame and not + // always) and makes using Mahogany quite annoying +#if 0 + wxASSERT_MSG( wxGetTopLevelParent(win) == g_activeFrame, + wxT("unfocusing window that hasn't gained focus properly") ) +#endif // 0 + g_activeFrameLostFocus = TRUE; } @@ -2332,6 +2389,7 @@ void wxWindowGTK::Init() m_isStaticBox = FALSE; m_isRadioButton = FALSE; + m_isListBox = FALSE; m_isFrame = FALSE; m_acceptsFocus = FALSE; @@ -3676,16 +3734,29 @@ static void SetInvokingWindow( wxMenu *menu, wxWindowGTK *win ) } } +// used to pass the coordinates from wxWindowGTK::DoPopupMenu() to +// wxPopupMenuPositionCallback() +// +// should be safe even in the MT case as the user can hardly popup 2 menus +// simultaneously, can he? static gint gs_pop_x = 0; static gint gs_pop_y = 0; -static void pop_pos_callback( GtkMenu * WXUNUSED(menu), - gint *x, gint *y, - wxWindowGTK *win ) +static void wxPopupMenuPositionCallback( GtkMenu *menu, + gint *x, gint *y, + gpointer WXUNUSED(user_data) ) { - win->ClientToScreen( &gs_pop_x, &gs_pop_y ); - *x = gs_pop_x; - *y = gs_pop_y; + // ensure that the menu appears entirely on screen + GtkRequisition req; + gtk_widget_get_child_requisition(GTK_WIDGET(menu), &req); + + wxSize sizeScreen = wxGetDisplaySize(); + + gint xmax = sizeScreen.x - req.width, + ymax = sizeScreen.y - req.height; + + *x = gs_pop_x < xmax ? gs_pop_x : xmax; + *y = gs_pop_y < ymax ? gs_pop_y : ymax; } bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) @@ -3700,6 +3771,7 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) gs_pop_x = x; gs_pop_y = y; + ClientToScreen( &gs_pop_x, &gs_pop_y ); bool is_waiting = TRUE; @@ -3708,12 +3780,12 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) gtk_menu_popup( GTK_MENU(menu->m_menu), - (GtkWidget *) NULL, // parent menu shell - (GtkWidget *) NULL, // parent menu item - (GtkMenuPositionFunc) pop_pos_callback, - (gpointer) this, // client data - 0, // button used to activate it - gs_timeLastClick // the time of activation + (GtkWidget *) NULL, // parent menu shell + (GtkWidget *) NULL, // parent menu item + wxPopupMenuPositionCallback, // function to position it + NULL, // client data + 0, // button used to activate it + gs_timeLastClick // the time of activation ); while (is_waiting)