commit 65fea3ff58cdb012340d7e5755188df213df480a (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Mar 10 11:48:12 2022 +0800 Fix menu bar activation on PGTK * src/gtkutil.c (menu_bar_button_pressed_cb): Only update menu bar if no menu is active, and the event window is not the widget window itself. Also make menu in use. * src/pgtkmenu.c (popup_deactivate_callback): Make menu not in use. * src/xdisp.c (redisplay_internal): Return if popup_activated also on PGTK. diff --git a/src/gtkutil.c b/src/gtkutil.c index 2a64781088..1b4ecaf949 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -3282,8 +3282,13 @@ menu_bar_button_pressed_cb (GtkWidget *widget, GdkEvent *event, { struct frame *f = user_data; - if (event->button.button < 4) - set_frame_menubar (f, true); + if (event->button.button < 4 + && event->button.window != gtk_widget_get_window (widget) + && !popup_activated ()) + { + pgtk_menu_set_in_use (true); + set_frame_menubar (f, true); + } return false; } diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c index 7a3bfea451..bd63af3b22 100644 --- a/src/pgtkmenu.c +++ b/src/pgtkmenu.c @@ -43,7 +43,7 @@ along with GNU Emacs. If not, see . */ #include /* Flag which when set indicates a dialog or menu has been posted by - Xt on behalf of one of the widget sets. */ + GTK on behalf of one of the widget sets. */ static int popup_activated_flag; /* Set menu_items_inuse so no other popup menu or dialog is created. */ @@ -132,7 +132,7 @@ pgtk_activate_menubar (struct frame *f) static void popup_deactivate_callback (GtkWidget *widget, gpointer client_data) { - popup_activated_flag = 0; + pgtk_menu_set_in_use (false); } /* Function that finds the frame for WIDGET and shows the HELP text diff --git a/src/xdisp.c b/src/xdisp.c index acb9cb7283..5cb58391dd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -16037,11 +16037,9 @@ redisplay_internal (void) if (!fr->glyphs_initialized_p) return; -#if defined (USE_X_TOOLKIT) || (defined (USE_GTK) && !defined (HAVE_PGTK)) || defined (HAVE_NS) +#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) if (popup_activated ()) - { - return; - } + return; #endif #if defined (HAVE_HAIKU) commit 4a845b2cd0e771b39b778daf4941e5c02fa8e6b8 Author: Po Lu Date: Thu Mar 10 09:16:39 2022 +0800 Fix stray button release events being reported on GTK 2 * src/xterm.c (handle_one_xevent): Drop ButtonRelease events that are destined for a popup menu. diff --git a/src/xterm.c b/src/xterm.c index 0d77ea0c19..5b1e102379 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12435,6 +12435,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, g_object_ref (copy->button.window); + if (popup_activated () + && xev->evtype == XI_ButtonRelease) + { + *finish = X_EVENT_DROP; + gtk_main_do_event (copy); + gdk_event_free (copy); + goto XI_OTHER; + } + gtk_main_do_event (copy); gdk_event_free (copy); #endif commit 70d63ead212b7ca1e561b869d44fddb14d0445af Author: Po Lu Date: Thu Mar 10 09:12:59 2022 +0800 Fix menu bar event detection on XI2 builds using Core Input * src/gtkutil.c (xg_get_gdk_scale): Always return 1 on GTK+ 2. (xg_event_is_for_menubar): Fix some ifdefs. * src/xterm.c (handle_one_xevent): Update a comment. diff --git a/src/gtkutil.c b/src/gtkutil.c index bf95c96642..2a64781088 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -266,6 +266,7 @@ xg_display_open (char *display_name, GdkDisplay **dpy) static int xg_get_gdk_scale (void) { +#ifdef HAVE_GTK3 const char *sscale = getenv ("GDK_SCALE"); if (sscale) @@ -274,6 +275,7 @@ xg_get_gdk_scale (void) if (0 < scale) return min (scale, INT_MAX); } +#endif return 1; } @@ -4223,13 +4225,13 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) } else { -#else +#endif rec.x = event->xbutton.x / scale; rec.y = event->xbutton.y / scale; -#endif #ifdef HAVE_XINPUT2 } #endif + rec.width = 1; rec.height = 1; diff --git a/src/xterm.c b/src/xterm.c index 68f7588af4..0d77ea0c19 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11652,11 +11652,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, #if defined (USE_X_TOOLKIT) || defined (USE_GTK) f = x_menubar_window_to_frame (dpyinfo, event); - /* For a down-event in the menu bar, - don't pass it to Xt right now. - Instead, save it away - and we will pass it to Xt from kbd_buffer_get_event. - That way, we can run some Lisp code first. */ + /* For a down-event in the menu bar, don't pass it to Xt or + GTK right away. Instead, save it and pass it to Xt or GTK + from kbd_buffer_get_event. That way, we can run some Lisp + code first. */ if (! popup_activated () #ifdef USE_GTK /* Gtk+ menus only react to the first three buttons. */ commit 2353893bd04bfee7c7659a758cf7c5072121a90c Author: Lars Ingebrigtsen Date: Wed Mar 9 17:37:36 2022 +0100 Fix regression in vtable-goto-object * lisp/emacs-lisp/vtable.el (vtable-goto-object): Fix moving to the object. diff --git a/lisp/emacs-lisp/vtable.el b/lisp/emacs-lisp/vtable.el index 2c61996637..d8577c1976 100644 --- a/lisp/emacs-lisp/vtable.el +++ b/lisp/emacs-lisp/vtable.el @@ -167,7 +167,7 @@ Return the position of the object if found, and nil if not." (let ((start (point))) (vtable-beginning-of-table) (save-restriction - (narrow-to-region (point) (vtable-end-of-table)) + (narrow-to-region (point) (save-excursion (vtable-end-of-table))) (if (text-property-search-forward 'vtable-object object #'eq) (progn (forward-line -1) commit 94f342438144c99bec90cc219283df2033866576 Author: Po Lu Date: Wed Mar 9 21:33:48 2022 +0800 Fix some issues with GTK native input and modifiers on GTK 2 * src/gtkutil.c (xg_widget_key_press_event_cb): Manually ignore modifier keys on GTK 2. diff --git a/src/gtkutil.c b/src/gtkutil.c index 4f9907f795..bf95c96642 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -6252,6 +6252,13 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event, if (event->key.is_modifier) goto done; +#ifndef HAVE_GTK3 + /* FIXME: event->key.is_modifier is not accurate on GTK 2. */ + + if (keysym >= GDK_KEY_Shift_L && keysym <= GDK_KEY_Hyper_R) + goto done; +#endif + /* First deal with keysyms which have defined translations to characters. */ if (keysym >= 32 && keysym < 128) commit fe8d49e1add8421afb16f5666bdbbabc7704f9c1 Author: Po Lu Date: Wed Mar 9 21:29:17 2022 +0800 Make XInput 2 features work on GTK 2 builds * src/xfns.c (setup_xi_event_mask): On GTK 2, select for button, motion, entry/exit and key events. * src/xmenu.c (create_and_show_popup_menu): Clear XI grab if appropriate. * src/xterm.c (handle_one_xevent): Pass some kinds of input extension events to GTK manually on versions of GTK+ that don't understand them. diff --git a/src/xfns.c b/src/xfns.c index cf5823c645..a3236efbcc 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -3579,7 +3579,7 @@ setup_xi_event_mask (struct frame *f) mask.mask_len = l; block_input (); -#ifndef USE_GTK +#ifndef HAVE_GTK3 mask.deviceid = XIAllMasterDevices; XISetMask (m, XI_ButtonPress); @@ -3587,8 +3587,10 @@ setup_xi_event_mask (struct frame *f) XISetMask (m, XI_Motion); XISetMask (m, XI_Enter); XISetMask (m, XI_Leave); +#ifndef USE_GTK XISetMask (m, XI_FocusIn); XISetMask (m, XI_FocusOut); +#endif XISetMask (m, XI_KeyPress); XISetMask (m, XI_KeyRelease); XISelectEvents (FRAME_X_DISPLAY (f), @@ -3596,7 +3598,7 @@ setup_xi_event_mask (struct frame *f) &mask, 1); memset (m, 0, l); -#endif /* !USE_GTK */ +#endif /* !HAVE_GTK3 */ #ifdef USE_X_TOOLKIT XISetMask (m, XI_KeyPress); diff --git a/src/xmenu.c b/src/xmenu.c index 4d0e5bd81c..d19fe13c29 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1527,6 +1527,23 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, if (i == 5) i = 0; } +#if !defined HAVE_GTK3 && defined HAVE_XINPUT2 + if (FRAME_DISPLAY_INFO (f)->num_devices) + { + for (int i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i) + { + if (FRAME_DISPLAY_INFO (f)->devices[i].grab) + { + FRAME_DISPLAY_INFO (f)->devices[i].grab = 0; + + XIUngrabDevice (FRAME_X_DISPLAY (f), + FRAME_DISPLAY_INFO (f)->devices[i].device_id, + CurrentTime); + } + } + } +#endif + /* Display the menu. */ gtk_widget_show_all (menu); diff --git a/src/xterm.c b/src/xterm.c index 772a9238a7..68f7588af4 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -10021,6 +10021,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, being passed to XtDispatchEvent. */ bool use_copy = false; XEvent copy; +#elif defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2 + GdkEvent *copy = NULL; + GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display); #endif *finish = X_EVENT_NORMAL; @@ -12186,6 +12189,20 @@ handle_one_xevent (struct x_display_info *dpyinfo, { x_display_set_last_user_time (dpyinfo, xev->time); +#if defined USE_GTK && !defined HAVE_GTK3 + /* Unlike on Motif, we can't select for XI + events on the scroll bar window under GTK+ 2. + So instead of that, just ignore XI wheel + events which land on a scroll bar. + + Here we assume anything which isn't the edit + widget window is a scroll bar. */ + + if (xev->child != None + && xev->child != FRAME_X_WINDOW (f)) + goto OTHER; +#endif + if (fabs (total_x) > 0 || fabs (total_y) > 0) { inev.ie.kind = (fabs (total_y) >= fabs (total_x) @@ -12390,6 +12407,37 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (XIMaskIsSet (xev->buttons.mask, 3)) copy.xbutton.state |= Button3Mask; } +#elif defined USE_GTK && !defined HAVE_GTK3 + copy = gdk_event_new (xev->evtype == XI_ButtonPress + ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE); + + copy->button.window = gdk_x11_window_lookup_for_display (gdpy, xev->event); + copy->button.send_event = xev->send_event; + copy->button.time = xev->time; + copy->button.x = xev->event_x; + copy->button.y = xev->event_y; + copy->button.x_root = xev->root_x; + copy->button.y_root = xev->root_y; + copy->button.state = xev->mods.effective; + copy->button.button = xev->detail; + + if (xev->buttons.mask_len) + { + if (XIMaskIsSet (xev->buttons.mask, 1)) + copy->button.state |= GDK_BUTTON1_MASK; + if (XIMaskIsSet (xev->buttons.mask, 2)) + copy->button.state |= GDK_BUTTON2_MASK; + if (XIMaskIsSet (xev->buttons.mask, 3)) + copy->button.state |= GDK_BUTTON3_MASK; + } + + if (!copy->button.window) + emacs_abort (); + + g_object_ref (copy->button.window); + + gtk_main_do_event (copy); + gdk_event_free (copy); #endif #ifdef HAVE_XINPUT2_1 commit b883e8bc65d314273b63da873e1cdbbac23978e9 Author: Po Lu Date: Wed Mar 9 20:43:59 2022 +0800 Fix GTK widgets not appearing inside child frames * src/xfns.c (x_set_parent_frame): Disable GTK's own frame synchronization in child frames. diff --git a/src/xfns.c b/src/xfns.c index c71f2b025f..cf5823c645 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -919,6 +919,9 @@ static void x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) { struct frame *p = NULL; +#ifdef HAVE_GTK3 + GdkWindow *window; +#endif if (!NILP (new_value) && (!FRAMEP (new_value) @@ -942,6 +945,14 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)), p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE); #endif + +#ifdef HAVE_GTK3 + if (p) + { + window = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)); + gdk_x11_window_set_frame_sync_enabled (window, false); + } +#endif unblock_input (); fset_parent_frame (f, new_value); commit 06d826d0cac4f82e9bf6ce2c1e38ddbc882a5220 Author: Po Lu Date: Wed Mar 9 16:28:33 2022 +0800 Fix error when creating frames on NS with no main window * nsfns.m (Fx_create_frame): If main window is not present, center frame window instead of cascading it. diff --git a/src/nsfns.m b/src/nsfns.m index 6256bd220d..720ed3f88e 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1503,7 +1503,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. [frame_window cascadeTopLeftFromPoint: top_left]; } else - [main_window center]; + [frame_window center]; } /* Make sure windows on this frame appear in calls to next-window