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()) {