From ecca5019989b0e7a78fee291c7d555968fe9ba74 Mon Sep 17 00:00:00 2001 From: osch Date: Thu, 16 May 2019 20:05:32 +0200 Subject: Handle mouse clicks in Alt+Tab Popup --- src/core/display.c | 83 +++++++++++++++++++++++++++++++++++++++----------- src/include/tabpopup.h | 5 ++- src/ui/tabpopup.c | 40 ++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 18 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index cbe0eb7e..055c15d1 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1592,6 +1592,37 @@ static gboolean maybe_send_event_to_gtk(MetaDisplay* display, XEvent* xevent) return TRUE; } +static gboolean +mouse_event_is_in_tab_popup (MetaDisplay *display, + MetaScreen *screen, + Window event_window, + int event_x, + int event_y, + int *popup_x, + int *popup_y) +{ + if (screen && screen->tab_popup) + { + int x, y; + Window child1, child2; + gboolean ok1 = XTranslateCoordinates (display->xdisplay, + event_window, event_window, + event_x, event_y, + &x, &y, &child1); + + Window popup_xid = meta_ui_tab_popup_get_xid(screen->tab_popup); + + gboolean ok2 = XTranslateCoordinates (display->xdisplay, + event_window, popup_xid, + event_x, event_y, + popup_x, popup_y, &child2); + + return (ok1 && ok2 && child1 == popup_xid); + } + else + return FALSE; +} + /** * This is the most important function in the whole program. It is the heart, * it is the nexus, it is the Grand Central Station of Marco's world. @@ -1803,26 +1834,44 @@ static gboolean event_callback(XEvent* event, gpointer data) display->grab_window == window) || grab_op_is_keyboard (display->grab_op)) { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u on window %s due to button press\n", - display->grab_op, - (display->grab_window ? - display->grab_window->desc : - "none")); - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + gboolean is_in_tab_popup = FALSE; + if (grab_op_is_keyboard (display->grab_op)) + { + MetaScreen *screen = meta_display_screen_for_root (display, event->xany.window); + int popup_x, popup_y; + is_in_tab_popup = mouse_event_is_in_tab_popup (display, + screen, + event->xany.window, + event->xbutton.x, + event->xbutton.y, + &popup_x, + &popup_y); + if (is_in_tab_popup && event->xbutton.button == Button1) + meta_ui_tab_popup_mouse_press(screen->tab_popup, popup_x, popup_y); + } + if (!is_in_tab_popup) { - MetaScreen *screen; meta_topic (META_DEBUG_WINDOW_OPS, - "Syncing to old stack positions.\n"); - screen = - meta_display_screen_for_root (display, event->xany.window); - - if (screen!=NULL) - meta_stack_set_positions (screen->stack, - display->grab_old_window_stacking); + "Ending grab op %u on window %s due to button press\n", + display->grab_op, + (display->grab_window ? + display->grab_window->desc : + "none")); + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + { + MetaScreen *screen; + meta_topic (META_DEBUG_WINDOW_OPS, + "Syncing to old stack positions.\n"); + screen = + meta_display_screen_for_root (display, event->xany.window); + + if (screen!=NULL) + meta_stack_set_positions (screen->stack, + display->grab_old_window_stacking); + } + meta_display_end_grab_op (display, + event->xbutton.time); } - meta_display_end_grab_op (display, - event->xbutton.time); } else if (window && display->grab_op == META_GRAB_OP_NONE) { diff --git a/src/include/tabpopup.h b/src/include/tabpopup.h index 630218b0..077ec909 100644 --- a/src/include/tabpopup.h +++ b/src/include/tabpopup.h @@ -69,7 +69,10 @@ void meta_ui_tab_popup_up (MetaTabPopup *popup); MetaTabEntryKey meta_ui_tab_popup_get_selected (MetaTabPopup *popup); void meta_ui_tab_popup_select (MetaTabPopup *popup, MetaTabEntryKey key); - +Window meta_ui_tab_popup_get_xid (MetaTabPopup *popup); +void meta_ui_tab_popup_mouse_press (MetaTabPopup *popup, + gint x, + gint y); #endif diff --git a/src/ui/tabpopup.c b/src/ui/tabpopup.c index 9f83fb64..b896b0e3 100644 --- a/src/ui/tabpopup.c +++ b/src/ui/tabpopup.c @@ -640,6 +640,46 @@ meta_ui_tab_popup_select (MetaTabPopup *popup, } } +Window +meta_ui_tab_popup_get_xid (MetaTabPopup *popup) +{ + if (popup != NULL && popup->window != NULL) + return gdk_x11_window_get_xid(gtk_widget_get_window(popup->window)); + else + return 0; +} + +void +meta_ui_tab_popup_mouse_press (MetaTabPopup *popup, + gint x, + gint y) +{ + GList *tmp = popup->entries; + gboolean found = FALSE; + while (tmp != NULL && !found) + { + TabEntry *te = tmp->data; + gint wx, wy; + if (gtk_widget_translate_coordinates(popup->window, + te->widget, + x, y, + &wx, &wy)) + { + GtkAllocation alloc; + gtk_widget_get_allocation(te->widget, &alloc); + found = (0 <= wx && wx < alloc.width && + 0 <= wy && wy < alloc.height); + if (found) + { + popup->current = tmp; + display_entry (popup, te); + } + } + tmp = tmp->next; + } +} + + #define META_TYPE_SELECT_IMAGE (meta_select_image_get_type ()) #define META_SELECT_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_IMAGE, MetaSelectImage)) -- cgit v1.2.1