From 86a8d138f2f3e366ccaa185fa86b97e49534dfd8 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Fri, 30 May 2025 16:44:26 +0200 Subject: Fix for #1260 - part2: improve position of menu button window under Wayland --- src/Fl_Menu_Button.cxx | 3 +++ src/Fl_Window_Driver.H | 2 ++ src/Fl_Window_Driver.cxx | 1 + src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 21 +++++++++++++++++---- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Fl_Menu_Button.cxx b/src/Fl_Menu_Button.cxx index 5321dbf48..8493127d7 100644 --- a/src/Fl_Menu_Button.cxx +++ b/src/Fl_Menu_Button.cxx @@ -18,6 +18,7 @@ #include #include #include +#include "Fl_Window_Driver.H" Fl_Menu_Button* Fl_Menu_Button::pressed_menu_button_ = NULL; @@ -68,7 +69,9 @@ const Fl_Menu_Item* Fl_Menu_Button::popup() { if (!box() || type()) { m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this); } else { + Fl_Window_Driver::current_menu_button = this; m = menu()->pulldown(x(), y(), w(), h(), 0, this); + Fl_Window_Driver::current_menu_button = NULL; } picked(m); pressed_menu_button_ = 0; diff --git a/src/Fl_Window_Driver.H b/src/Fl_Window_Driver.H index 865c57af9..afa7017c5 100644 --- a/src/Fl_Window_Driver.H +++ b/src/Fl_Window_Driver.H @@ -206,6 +206,8 @@ public: static int *menu_offset_y(Fl_Window*); static bool is_floating_title(Fl_Window *); static void scroll_to_selected_item(Fl_Window *); + // non-NULL when an Fl_Menu_Button is being pulled down + static class Fl_Menu_Button *current_menu_button; virtual fl_uintptr_t os_id() { return 0; } virtual void allow_expand_outside_parent() {} diff --git a/src/Fl_Window_Driver.cxx b/src/Fl_Window_Driver.cxx index ccf5f1a07..4abeda869 100644 --- a/src/Fl_Window_Driver.cxx +++ b/src/Fl_Window_Driver.cxx @@ -31,6 +31,7 @@ extern void fl_throw_focus(Fl_Widget *o); +Fl_Menu_Button *Fl_Window_Driver::current_menu_button = NULL; /** Create a new Window Driver. diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 9ddf78b72..c0963fa66 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include // for ceil() #include // for pid_t @@ -1325,7 +1326,18 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi struct xdg_positioner *positioner = xdg_wm_base_create_positioner(scr_driver->xdg_wm_base); //xdg_positioner_get_version(positioner) <== gives 1 under Debian and Sway int popup_x, popup_y; - if (Fl_Window_Driver::menu_title(pWindow) && Fl_Window_Driver::menu_bartitle(pWindow)) { + if (Fl_Window_Driver::current_menu_button && !Fl_Window_Driver::menu_leftorigin(pWindow)) { + xdg_positioner_set_anchor_rect(positioner, + Fl_Window_Driver::current_menu_button->x() * f, + Fl_Window_Driver::current_menu_button->y() * f, + Fl_Window_Driver::current_menu_button->w() * f, + Fl_Window_Driver::current_menu_button->h() * f); + popup_x = Fl_Window_Driver::current_menu_button->x() * f; + popup_y = 0; + if (parent_xid->kind == Fl_Wayland_Window_Driver::DECORATED && !origin_win->fullscreen_active()) + libdecor_frame_translate_coordinate(parent_xid->frame, popup_x, popup_y, + &popup_x, &popup_y); + } else if (Fl_Window_Driver::menu_title(pWindow) && Fl_Window_Driver::menu_bartitle(pWindow)) { xdg_positioner_set_anchor_rect(positioner, 0, 0, Fl_Window_Driver::menu_title(pWindow)->w() * f, Fl_Window_Driver::menu_title(pWindow)->h() * f); @@ -1344,7 +1356,7 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi // prevent first popup from going above the permissible source window popup_y = fl_max(popup_y, - pWindow->h() * f); } - if (parent_xid->kind == Fl_Wayland_Window_Driver::DECORATED) + if (parent_xid->kind == Fl_Wayland_Window_Driver::DECORATED && !origin_win->fullscreen_active()) libdecor_frame_translate_coordinate(parent_xid->frame, popup_x, popup_y, &popup_x, &popup_y); xdg_positioner_set_anchor_rect(positioner, popup_x, 0, 1, 1); @@ -1371,11 +1383,12 @@ bool Fl_Wayland_Window_Driver::process_menu_or_tooltip(struct wld_window *new_wi if ( !(parent_win->fullscreen_active() && Fl_Wayland_Screen_Driver::compositor == Fl_Wayland_Screen_Driver::MUTTER && ((!Fl_Window_Driver::menu_title(pWindow) && !Fl_Window_Driver::menu_leftorigin(pWindow)) || - Fl_Window_Driver::menu_bartitle(pWindow)) && pWindow->y() < 10) + Fl_Window_Driver::menu_bartitle(pWindow)) && pWindow->y() < 10 && !Fl_Window_Driver::current_menu_button) ) { // Condition above is only to bypass Mutter bug for fullscreen windows (see #1061) constraint |= (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y); - if (Fl_Window_Driver::menu_bartitle(pWindow) && !Fl_Window_Driver::menu_leftorigin(pWindow)) { + if ((Fl_Window_Driver::current_menu_button || Fl_Window_Driver::menu_bartitle(pWindow)) && + !Fl_Window_Driver::menu_leftorigin(pWindow)) { constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y; } xdg_positioner_set_constraint_adjustment(positioner, constraint); -- cgit v1.2.3