From 1d0e63ea784f0d8e3835f3517d47c11ecf79a79b Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:25:19 +0200 Subject: [PATCH] Improve member function Fl_Wayland_Screen_Driver::surface_to_window() Rename it to Fl_Wayland_Window_Driver::surface_to_window() and avoid loop over all mapped FLTK windows that used to be performed. --- documentation/src/wayland.dox | 8 ++-- .../Wayland/Fl_Wayland_Screen_Driver.H | 1 - .../Wayland/Fl_Wayland_Screen_Driver.cxx | 38 +++++++------------ .../Wayland/Fl_Wayland_Window_Driver.H | 1 + .../Wayland/Fl_Wayland_Window_Driver.cxx | 10 +++++ .../Wayland/fl_wayland_clipboard_dnd.cxx | 4 +- 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/documentation/src/wayland.dox b/documentation/src/wayland.dox index 78fb12619..4c9fbfd94 100644 --- a/documentation/src/wayland.dox +++ b/documentation/src/wayland.dox @@ -126,9 +126,9 @@ necessary glue C source file from a given XML file. For example, for FLTK to use protocol, these commands are run at build time to generate a .c file that will be compiled into libfltk and a header file that FLTK code will include: \code -set(PROTOCOLS /usr/share/wayland-protocols) -wayland-scanner private-code ${PROTOCOLS}/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.c -wayland-scanner client-header ${PROTOCOLS}/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h +PROTOCOLS=`pkg-config --variable=pkgdatadir wayland-protocols` +wayland-scanner private-code $PROTOCOLS/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.c +wayland-scanner client-header $PROTOCOLS/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h \endcode Similar operations are performed for FLTK to use protocols xdg decoration unstable v1 and text input unstable v3. @@ -232,7 +232,7 @@ Wayland defines objects called surfaces of type struct wl_surface. A Wa receive user input, and define a local coordinate system". Buffers allow the client app to draw to surfaces (see below). FLTK makes no use of local coordinate systems. FLTK creates a surface with function \c wl_compositor_create_surface() each time an Fl_Window is show()'n. -Static member function Fl_Wayland_Screen_Driver::surface_to_window(struct wl_surface *) +Static member function Fl_Wayland_Window_Driver::surface_to_window(struct wl_surface *) gives the \c Fl_Window* corresponding to the surface given in argument. Function \c wl_surface_add_listener() associates the surface with a listener which allows to associate each surface with the display where it is mapped. FLTK recognizes 4 distinct diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H index 1b2ca3141..a01c9b013 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H @@ -85,7 +85,6 @@ public: // static member functions static void insertion_point_location(int x, int y, int height); static bool insertion_point_location(int *px, int *py, int *pwidth, int *pheight); - static Fl_Window *surface_to_window(struct wl_surface *); static bool own_output(struct wl_output *output); // member variables diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 0ecf5b407..e695cb5e1 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -217,21 +217,9 @@ static inline void checkdouble() { struct wl_display *Fl_Wayland_Screen_Driver::wl_display = NULL; -Fl_Window *Fl_Wayland_Screen_Driver::surface_to_window(struct wl_surface *surface) { - if (surface) { - Fl_X *xp = Fl_X::first; - while (xp) { - if (((struct wld_window*)xp->xid)->wl_surface == surface) return xp->w; - xp = xp->next; - } - } - return NULL; -} - - static Fl_Window *event_coords_from_surface(struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); if (!win) return NULL; int delta_x = 0, delta_y = 0; while (win->parent()) { @@ -277,7 +265,7 @@ static void pointer_leave(void *data, { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; if (seat->pointer_focus == surface) seat->pointer_focus = NULL; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); if (win) { Fl::belowmouse(0); set_event_xy(win); @@ -319,7 +307,7 @@ static void pointer_button(void *data, struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; seat->serial = serial; int event = 0; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(seat->pointer_focus); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(seat->pointer_focus); if (!win) return; win = win->top_window(); wld_event_time = time; @@ -355,7 +343,7 @@ static void pointer_axis(void *data, wl_fixed_t value) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(seat->pointer_focus); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(seat->pointer_focus); if (!win) return; wld_event_time = time; int delta = wl_fixed_to_int(value) / 10; @@ -564,7 +552,7 @@ static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, struct wl_array *keys) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; -//fprintf(stderr, "keyboard enter fl_win=%p; keys pressed are: ", Fl_Wayland_Screen_Driver::surface_to_window(surface)); +//fprintf(stderr, "keyboard enter fl_win=%p; keys pressed are: ", Fl_Wayland_Window_Driver::surface_to_window(surface)); // Replace wl_array_for_each(p, keys) rejected by C++ for (uint32_t *p = (uint32_t *)(keys)->data; (const char *) p < ((const char *) (keys)->data + (keys)->size); @@ -576,7 +564,7 @@ static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, //fprintf(stderr, "\n"); seat->keyboard_surface = surface; seat->keyboard_enter_serial = serial; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); if (win) { Fl::handle(FL_FOCUS, win); fl_wl_find(fl_wl_xid(win)); @@ -712,7 +700,7 @@ static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, int for_key_vector = process_wld_key(seat->xkb_state, key, &keycode, &sym); /*xkb_keysym_get_name(sym, buf, sizeof(buf)); const char *action = (state == WL_KEYBOARD_KEY_STATE_PRESSED ? "press" : "release"); -fprintf(stderr, "key %s: sym: %-12s(%d) code:%u fl_win=%p, ", action, buf, sym, keycode, Fl_Wayland_Screen_Driver::surface_to_window(seat->keyboard_surface));*/ +fprintf(stderr, "key %s: sym: %-12s(%d) code:%u fl_win=%p, ", action, buf, sym, keycode, Fl_Wayland_Window_Driver::surface_to_window(seat->keyboard_surface));*/ xkb_state_key_get_utf8(seat->xkb_state, keycode, buf, sizeof(buf)); //fprintf(stderr, "utf8: '%s' e_length=%d [%d]\n", buf, (int)strlen(buf), *buf); Fl::e_keysym = for_key_vector; @@ -759,7 +747,7 @@ fprintf(stderr, "key %s: sym: %-12s(%d) code:%u fl_win=%p, ", action, buf, sym, int event = (state == WL_KEYBOARD_KEY_STATE_PRESSED ? FL_KEYDOWN : FL_KEYUP); // Send event to focus-containing top window as defined by FLTK, // otherwise send it to Wayland-defined focus window - Fl_Window *win = ( Fl::focus() ? Fl::focus()->top_window() : Fl_Wayland_Screen_Driver::surface_to_window(seat->keyboard_surface) ); + Fl_Window *win = ( Fl::focus() ? Fl::focus()->top_window() : Fl_Wayland_Window_Driver::surface_to_window(seat->keyboard_surface) ); if (win) { set_event_xy(win); Fl::e_is_click = 0; @@ -777,9 +765,9 @@ static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface) { struct Fl_Wayland_Screen_Driver::seat *seat = (struct Fl_Wayland_Screen_Driver::seat*)data; -//fprintf(stderr, "keyboard leave fl_win=%p\n", Fl_Wayland_Screen_Driver::surface_to_window(surface)); +//fprintf(stderr, "keyboard leave fl_win=%p\n", Fl_Wayland_Window_Driver::surface_to_window(surface)); seat->keyboard_surface = NULL; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); if (!win && Fl::focus()) win = Fl::focus()->top_window(); if (win) Fl::handle(FL_UNFOCUS, win); key_vector.size(0); @@ -851,7 +839,7 @@ void text_input_preedit_string(void *data, struct zwp_text_input_v3 *zwp_text_in Fl::e_length = text ? strlen(text) : 0; Fl::e_keysym = 'a'; // fake a simple key struct wl_surface *surface = (struct wl_surface*)data; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); set_event_xy(win); Fl::e_is_click = 0; Fl::handle(FL_KEYDOWN, win); @@ -863,7 +851,7 @@ void text_input_commit_string(void *data, struct zwp_text_input_v3 *zwp_text_inp Fl::e_text = (char*)text; Fl::e_length = strlen(text); struct wl_surface *surface = (struct wl_surface*)data; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); set_event_xy(win); Fl::e_is_click = 0; Fl::handle(FL_KEYDOWN, win); @@ -1567,7 +1555,7 @@ int Fl_Wayland_Screen_Driver::get_mouse(int &xx, int &yy) { open_display(); xx = Fl::e_x_root; yy = Fl::e_y_root; if (!seat->pointer_focus) return 0; - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(seat->pointer_focus); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(seat->pointer_focus); if (!win) return 0; int snum = Fl_Window_Driver::driver(win)->screen_num(); //printf("get_mouse(%dx%d)->%d\n", xx, yy, snum); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H index 9ab0807aa..00afa6c62 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.H @@ -84,6 +84,7 @@ public: virtual ~Fl_Wayland_Window_Driver(); static struct wld_window *wld_window; static void redraw(struct wld_window *window); + static Fl_Window *surface_to_window(struct wl_surface *); static inline Fl_Wayland_Window_Driver* driver(const Fl_Window *w) {return (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(w);} static void resize_after_screen_change(void *data); diff --git a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx index 24d87c15c..89b9a2953 100644 --- a/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx @@ -688,6 +688,16 @@ static struct wl_surface_listener surface_listener = { }; +Fl_Window *Fl_Wayland_Window_Driver::surface_to_window(struct wl_surface *surface) { + if (surface) { + if (wl_proxy_get_listener((struct wl_proxy *)surface) == &surface_listener) { + return ((struct wld_window *)wl_surface_get_user_data(surface))->fl_win; + } + } + return NULL; +} + + static void handle_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data) { diff --git a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx index 535d481fc..d65b2957f 100644 --- a/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx +++ b/src/drivers/Wayland/fl_wayland_clipboard_dnd.cxx @@ -406,7 +406,7 @@ static uint32_t fl_dnd_serial; static void data_device_handle_enter(void *data, struct wl_data_device *data_device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) { - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface); //printf("Drag entered our surface %p(win=%p) at %dx%d\n", surface, win, wl_fixed_to_int(x), wl_fixed_to_int(y)); if (win) { fl_dnd_target_surface = surface; @@ -437,7 +437,7 @@ static void data_device_handle_motion(void *data, struct wl_data_device *data_de int ret = 0; if (fl_dnd_target_window) { float f = Fl::screen_scale(fl_dnd_target_window->screen_num()); - Fl_Window *win = Fl_Wayland_Screen_Driver::surface_to_window(fl_dnd_target_surface); + Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(fl_dnd_target_surface); Fl::e_x = wl_fixed_to_int(x) / f; Fl::e_y = wl_fixed_to_int(y) / f; while (win->parent()) {