diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Menu.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_Window_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 19 |
4 files changed, 30 insertions, 0 deletions
diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx index d67b116d0..f3400bd9a 100644 --- a/src/Fl_Menu.cxx +++ b/src/Fl_Menu.cxx @@ -163,6 +163,7 @@ public: menuwindow* as_menuwindow() FL_OVERRIDE { return this; } int menubartitle; menuwindow *origin; + int offset_y; }; Fl_Window *menuwindow::parent_ = NULL; @@ -224,6 +225,12 @@ int Fl_Window_Driver::menu_selected(Fl_Window *win) { return (mwin ? mwin->selected : -1); } +/** Accessor to the address of the offset_y member variable of class menuwindow */ +int *Fl_Window_Driver::menu_offset_y(Fl_Window *win) { + menuwindow *mwin = to_menuwindow(win); + return (mwin ? &(mwin->offset_y) : NULL); +} + /** Returns whether win is a non-menubar menutitle */ bool Fl_Window_Driver::is_floating_title(Fl_Window *win) { if (!win->menu_window()) return false; @@ -371,6 +378,7 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp, int tx = X, ty = Y; menubartitle = menubar_title; origin = NULL; + offset_y = 0; Fl_Window_Driver::driver(this)->menu_window_area(scr_x, scr_y, scr_w, scr_h); if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w; diff --git a/src/Fl_Window_Driver.H b/src/Fl_Window_Driver.H index 0149d28b0..9d7588d9d 100644 --- a/src/Fl_Window_Driver.H +++ b/src/Fl_Window_Driver.H @@ -200,6 +200,7 @@ public: static int menu_itemheight(Fl_Window*); static int menu_bartitle(Fl_Window*); static int menu_selected(Fl_Window*); + static int *menu_offset_y(Fl_Window*); static bool is_floating_title(Fl_Window *); static void scroll_to_selected_item(Fl_Window *); static bool is_menutitle(Fl_Window *); diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index a95cce8fe..2a379d57a 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -219,6 +219,8 @@ static Fl_Window *event_coords_from_surface(struct wl_surface *surface, Fl::e_x = wl_fixed_to_int(surface_x) / f + delta_x; Fl::e_x_root = Fl::e_x + win->x(); Fl::e_y = wl_fixed_to_int(surface_y) / f + delta_y; + int *poffset = Fl_Window_Driver::menu_offset_y(win); + if (poffset) Fl::e_y -= *poffset; Fl::e_y_root = Fl::e_y + win->y(); return win; } diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 7ea0b948f..b4a5f6ebc 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -356,6 +356,10 @@ void Fl_Wayland_Window_Driver::make_current() { &window->buffer->draw_buffer_needs_commit); } ((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(window->buffer, f * wld_s); + int *poffset = Fl_Window_Driver::menu_offset_y(pWindow); + if (poffset) { // for tall menu windows under KDE to offset drawing inside window + cairo_translate(window->buffer->cairo_, 0, *poffset); + } cairo_rectangle_int_t *extents = subRect(); if (extents) { // make damage-to-buffer not to leak outside parent Fl_Region clip_region = fl_graphics_driver->XRectangleRegion(extents->x, extents->y, @@ -1741,6 +1745,21 @@ void Fl_Wayland_Window_Driver::subRect(cairo_rectangle_int_t *r) { void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) { if (y == pWindow->y()) return; + if (Fl_Wayland_Screen_Driver::compositor == Fl_Wayland_Screen_Driver::KDE) { + // The KDE compositor refuses to position a popup such that it extends above + // the top of the screen. Therefore, instead of sliding the popup window + // on the display, we slide the drawing inside the fixed popup via + // member variable offset_y of the menuwindow class, and we redraw the popup + // content. It's also useful to make such tall popup window transparent. + *Fl_Window_Driver::menu_offset_y(pWindow) += (y - pWindow->y()); + struct wld_window *xid = fl_wl_xid(pWindow); + wl_surface_set_opaque_region(xid->wl_surface, NULL); + memset(xid->buffer->draw_buffer, 0, xid->buffer->data_size); + //printf("offset_y=%d\n", *Fl_Window_Driver::menu_offset_y(pWindow)); + this->y(y); + pWindow->redraw(); + return; + } struct wld_window * xid_menu = fl_wl_xid(pWindow); //printf("reposition %dx%d[cur=%d] menu->state=%d\n", x, y, pWindow->y(), xid_menu->state); struct xdg_popup *old_popup = xid_menu->xdg_popup; |
