summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Menu.cxx8
-rw-r--r--src/Fl_Window_Driver.H1
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx2
-rw-r--r--src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx19
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;