diff options
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 144 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.h | 12 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.cpp | 76 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.h | 15 |
4 files changed, 125 insertions, 122 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 6a419fc718d..c360423c256 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -786,7 +786,7 @@ static void relative_pointer_handle_relative_motion( { input_t *input = static_cast<input_t *>(data); if (wl_surface *focus_surface = input->pointer.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); const wl_fixed_t scale = win->scale(); const wl_fixed_t xy_next[2] = { input->pointer.xy[0] + (dx / scale), @@ -810,7 +810,7 @@ static void dnd_events(const input_t *const input, const GHOST_TEventType event) { /* NOTE: `input->data_offer_dnd_mutex` must already be locked. */ if (wl_surface *focus_surface = input->focus_dnd) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); const wl_fixed_t scale = win->scale(); const int event_xy[2] = { wl_fixed_to_int(scale * input->data_offer_dnd->dnd.xy[0]), @@ -992,6 +992,10 @@ static void data_device_handle_enter(void *data, const wl_fixed_t y, struct wl_data_offer *id) { + if (!ghost_wl_surface_own(surface)) { + return; + } + input_t *input = static_cast<input_t *>(data); std::lock_guard lock{input->data_offer_dnd_mutex}; @@ -1077,9 +1081,7 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat static constexpr const char *file_proto = "file://"; static constexpr const char *crlf = "\r\n"; - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_find(surface); - GHOST_ASSERT(win != nullptr, "Unable to find window for drop event from surface"); - + GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); std::vector<std::string> uris; size_t pos = 0; @@ -1238,12 +1240,13 @@ static void cursor_surface_handle_enter(void *data, struct wl_surface * /*wl_surface*/, struct wl_output *output) { - input_t *input = static_cast<input_t *>(data); - for (const output_t *reg_output : input->system->outputs()) { - if (reg_output->wl_output == output) { - input->cursor.outputs.insert(reg_output); - } + if (!ghost_wl_output_own(output)) { + return; } + + input_t *input = static_cast<input_t *>(data); + const output_t *reg_output = ghost_wl_output_user_data(output); + input->cursor.outputs.insert(reg_output); update_cursor_scale(input->cursor, input->system->shm()); } @@ -1251,12 +1254,13 @@ static void cursor_surface_handle_leave(void *data, struct wl_surface * /*wl_surface*/, struct wl_output *output) { - input_t *input = static_cast<input_t *>(data); - for (const output_t *reg_output : input->system->outputs()) { - if (reg_output->wl_output == output) { - input->cursor.outputs.erase(reg_output); - } + if (!(output && ghost_wl_output_own(output))) { + return; } + + input_t *input = static_cast<input_t *>(data); + const output_t *reg_output = ghost_wl_output_user_data(output); + input->cursor.outputs.erase(reg_output); update_cursor_scale(input->cursor, input->system->shm()); } @@ -1278,7 +1282,11 @@ static void pointer_handle_enter(void *data, const wl_fixed_t surface_x, const wl_fixed_t surface_y) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + if (!ghost_wl_surface_own(surface)) { + return; + } + + GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); win->activate(); @@ -1307,8 +1315,8 @@ static void pointer_handle_leave(void *data, { /* First clear the `pointer.wl_surface`, since the window won't exist when closing the window. */ static_cast<input_t *>(data)->pointer.wl_surface = nullptr; - if (surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + if (surface && ghost_wl_surface_own(surface)) { + GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); win->deactivate(); } } @@ -1324,7 +1332,7 @@ static void pointer_handle_motion(void *data, input->pointer.xy[1] = surface_y; if (wl_surface *focus_surface = input->pointer.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); const wl_fixed_t scale = win->scale(); input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), GHOST_kEventCursorMove, @@ -1383,7 +1391,7 @@ static void pointer_handle_button(void *data, input->pointer.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED); if (wl_surface *focus_surface = input->pointer.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventButton( input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE)); } @@ -1402,7 +1410,7 @@ static void pointer_handle_axis(void *data, } if (wl_surface *focus_surface = input->pointer.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventWheel( input->system->getMilliSeconds(), win, std::signbit(value) ? +1 : -1)); } @@ -1474,6 +1482,10 @@ static void tablet_tool_handle_proximity_in(void *data, struct zwp_tablet_v2 * /*tablet*/, struct wl_surface *surface) { + if (!ghost_wl_surface_own(surface)) { + return; + } + tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data); tool_input->proximity = true; @@ -1492,7 +1504,7 @@ static void tablet_tool_handle_proximity_in(void *data, /* In case pressure isn't supported. */ td.Pressure = 1.0f; - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(input->tablet.wl_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(input->tablet.wl_surface); win->activate(); @@ -1520,7 +1532,7 @@ static void tablet_tool_handle_down(void *data, input->tablet.buttons.set(ebutton, true); if (wl_surface *focus_surface = input->tablet.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventButton( input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data)); } @@ -1536,7 +1548,7 @@ static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_ input->tablet.buttons.set(ebutton, false); if (wl_surface *focus_surface = input->tablet.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventButton( input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data)); } @@ -1608,7 +1620,7 @@ static void tablet_tool_handle_wheel(void *data, tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(data); input_t *input = tool_input->input; if (wl_surface *focus_surface = input->tablet.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventWheel(input->system->getMilliSeconds(), win, clicks)); } } @@ -1648,7 +1660,7 @@ static void tablet_tool_handle_button(void *data, input->tablet.buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED); if (wl_surface *focus_surface = input->tablet.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventButton( input->system->getMilliSeconds(), etype, win, ebutton, tool_input->data)); } @@ -1661,7 +1673,7 @@ static void tablet_tool_handle_frame(void *data, input_t *input = tool_input->input; if (wl_surface *focus_surface = input->tablet.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); const wl_fixed_t scale = win->scale(); input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), GHOST_kEventCursorMove, @@ -1813,6 +1825,10 @@ static void keyboard_handle_enter(void *data, struct wl_surface *surface, struct wl_array * /*keys*/) { + if (!ghost_wl_surface_own(surface)) { + return; + } + input_t *input = static_cast<input_t *>(data); input->keyboard.serial = serial; input->keyboard.wl_surface = surface; @@ -1827,8 +1843,12 @@ static void keyboard_handle_enter(void *data, static void keyboard_handle_leave(void *data, struct wl_keyboard * /*wl_keyboard*/, const uint32_t /*serial*/, - struct wl_surface * /*surface*/) + struct wl_surface *surface) { + if (!(surface && ghost_wl_surface_own(surface))) { + return; + } + input_t *input = static_cast<input_t *>(data); input->keyboard.wl_surface = nullptr; @@ -1983,7 +2003,7 @@ static void keyboard_handle_key(void *data, input->data_source_serial = serial; if (wl_surface *focus_surface = input->keyboard.wl_surface) { - GHOST_IWindow *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_IWindow *win = ghost_wl_surface_user_data(focus_surface); input->system->pushEvent(new GHOST_EventKey( input->system->getMilliSeconds(), etype, win, gkey, '\0', utf8_buf, false)); } @@ -2008,7 +2028,7 @@ static void keyboard_handle_key(void *data, input_t *input = payload->input; if (wl_surface *focus_surface = input->keyboard.wl_surface) { - GHOST_IWindow *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_IWindow *win = ghost_wl_surface_user_data(focus_surface); GHOST_SystemWayland *system = input->system; /* Calculate this value every time in case modifier keys are pressed. */ char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'}; @@ -2378,6 +2398,9 @@ static void global_handle_add(void *data, output_t *output = new output_t; output->wl_output = static_cast<wl_output *>( wl_registry_bind(wl_registry, name, &wl_output_interface, 2)); + ghost_wl_output_tag(output->wl_output); + wl_output_set_user_data(output->wl_output, output); + display->outputs.push_back(output); wl_output_add_listener(output->wl_output, &output_listener, output); @@ -2692,7 +2715,7 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) co } if (wl_surface *focus_surface = input_state->wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); return getCursorPositionClientRelative_impl(input_state, win, x, y); } return GHOST_kFailure; @@ -2708,7 +2731,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(const int32_t x, const int /* Intentionally different from `getCursorPosition` which supports both tablet & pointer. * In the case of setting the cursor location, tablets don't support this. */ if (wl_surface *focus_surface = input->pointer.wl_surface) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(focus_surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(focus_surface); return setCursorPositionClientRelative_impl(input, win, x, y); } return GHOST_kFailure; @@ -3255,7 +3278,7 @@ static bool setCursorGrab_use_software_confine(const GHOST_TGrabCursorMode mode, if (mode != GHOST_kGrabNormal) { return false; } - const GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface(surface); + const GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); if (!win) { return false; } @@ -3284,6 +3307,35 @@ static input_grab_state_t input_grab_state_from_mode(const GHOST_TGrabCursorMode /** \} */ /* -------------------------------------------------------------------- */ +/** \name Public WAYLAND Proxy Ownership API + * \{ */ + +static const char *ghost_wl_output_tag_id = "GHOST-output"; +static const char *ghost_wl_surface_tag_id = "GHOST-window"; + +bool ghost_wl_output_own(const struct wl_output *output) +{ + return wl_proxy_get_tag((struct wl_proxy *)output) == &ghost_wl_output_tag_id; +} + +bool ghost_wl_surface_own(const struct wl_surface *surface) +{ + return wl_proxy_get_tag((struct wl_proxy *)surface) == &ghost_wl_surface_tag_id; +} + +void ghost_wl_output_tag(struct wl_output *output) +{ + wl_proxy_set_tag((struct wl_proxy *)output, &ghost_wl_output_tag_id); +} + +void ghost_wl_surface_tag(struct wl_surface *surface) +{ + wl_proxy_set_tag((struct wl_proxy *)surface, &ghost_wl_surface_tag_id); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Public WAYLAND Direct Data Access * * Expose some members via methods. @@ -3336,14 +3388,20 @@ wl_shm *GHOST_SystemWayland::shm() const /** \name Public WAYLAND Query Access * \{ */ -output_t *GHOST_SystemWayland::output_find_by_wl(const struct wl_output *output) const +struct output_t *ghost_wl_output_user_data(struct wl_output *wl_output) { - for (output_t *reg_output : this->outputs()) { - if (reg_output->wl_output == output) { - return reg_output; - } - } - return nullptr; + GHOST_ASSERT(wl_output, "output must not be NULL"); + GHOST_ASSERT(ghost_wl_output_own(wl_output), "output is not owned by GHOST"); + output_t *output = static_cast<output_t *>(wl_output_get_user_data(wl_output)); + return output; +} + +GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *surface) +{ + GHOST_ASSERT(surface, "surface must not be NULL"); + GHOST_ASSERT(ghost_wl_surface_own(surface), "surface is not owned by GHOST"); + GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface)); + return win; } /** \} */ @@ -3433,7 +3491,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod if (mode_current == GHOST_kGrabWrap) { /* Since this call is initiated by Blender, we can be sure the window wasn't closed * by logic outside this function - as the window was needed to make this call. */ - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); GHOST_ASSERT(win, "could not find window from surface when un-grabbing!"); GHOST_Rect bounds; @@ -3472,7 +3530,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod else if (mode_current == GHOST_kGrabHide) { if ((init_grab_xy[0] != input->grab_lock_xy[0]) || (init_grab_xy[1] != input->grab_lock_xy[1])) { - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); const int scale = win->scale(); const wl_fixed_t xy_next[2] = { wl_fixed_from_int(init_grab_xy[0]) / scale, @@ -3526,7 +3584,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod if (mode == GHOST_kGrabHide) { /* Set the initial position to detect any changes when un-grabbing, * otherwise the unlocked cursor defaults to un-locking in-place. */ - GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); const int scale = win->scale(); init_grab_xy[0] = wl_fixed_to_int(scale * input->pointer.xy[0]); init_grab_xy[1] = wl_fixed_to_int(scale * input->pointer.xy[1]); diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index cf9ec5d0757..e336b02ec9e 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -27,6 +27,14 @@ class GHOST_WindowWayland; struct display_t; +bool ghost_wl_output_own(const struct wl_output *output); +void ghost_wl_output_tag(struct wl_output *output); +struct output_t *ghost_wl_output_user_data(struct wl_output *output); + +bool ghost_wl_surface_own(const struct wl_surface *surface); +void ghost_wl_surface_tag(struct wl_surface *surface); +GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *surface); + struct output_t { struct wl_output *wl_output = nullptr; struct zxdg_output_v1 *xdg_output = nullptr; @@ -147,10 +155,6 @@ class GHOST_SystemWayland : public GHOST_System { wl_shm *shm() const; - /* WAYLAND query access. */ - - output_t *output_find_by_wl(const struct wl_output *output) const; - /* WAYLAND utility functions. */ void selection_set(const std::string &selection); diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 6cae60fc4b5..d26dfe0e7e6 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -323,8 +323,12 @@ static void surface_handle_enter(void *data, struct wl_surface * /*wl_surface*/, struct wl_output *output) { + if (!ghost_wl_output_own(output)) { + return; + } + output_t *reg_output = ghost_wl_output_user_data(output); GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(data); - if (win->outputs_enter_wl(output)) { + if (win->outputs_enter(reg_output)) { win->outputs_changed_update_scale(); } } @@ -333,9 +337,13 @@ static void surface_handle_leave(void *data, struct wl_surface * /*wl_surface*/, struct wl_output *output) { - GHOST_WindowWayland *w = static_cast<GHOST_WindowWayland *>(data); - if (w->outputs_leave_wl(output)) { - w->outputs_changed_update_scale(); + if (!ghost_wl_output_own(output)) { + return; + } + output_t *reg_output = ghost_wl_output_user_data(output); + GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(data); + if (win->outputs_leave(reg_output)) { + win->outputs_changed_update_scale(); } } @@ -398,7 +406,9 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, /* Window surfaces. */ w->wl_surface = wl_compositor_create_surface(m_system->compositor()); - wl_surface_set_buffer_scale(this->surface(), w->scale); + ghost_wl_surface_tag(w->wl_surface); + + wl_surface_set_buffer_scale(w->wl_surface, w->scale); wl_surface_add_listener(w->wl_surface, &wl_surface_listener, this); @@ -810,42 +820,6 @@ const std::vector<output_t *> &GHOST_WindowWayland::outputs() /** \} */ /* -------------------------------------------------------------------- */ -/** \name Public WAYLAND Query Access - * \{ */ - -GHOST_WindowWayland *GHOST_WindowWayland::from_surface_find(const wl_surface *surface) -{ - GHOST_ASSERT(surface, "argument must not be NULL"); - for (GHOST_IWindow *iwin : window_manager->getWindows()) { - GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(iwin); - if (surface == win->surface()) { - return win; - } - } - return nullptr; -} - -GHOST_WindowWayland *GHOST_WindowWayland::from_surface_mut(wl_surface *surface) -{ - GHOST_ASSERT(surface, "argument must not be NULL"); - GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface)); - GHOST_ASSERT(win == GHOST_WindowWayland::from_surface_find(surface), - "Inconsistent window state, consider using \"from_surface_find\""); - return win; -} - -const GHOST_WindowWayland *GHOST_WindowWayland::from_surface(const wl_surface *surface) -{ - const GHOST_WindowWayland *win = static_cast<const GHOST_WindowWayland *>( - wl_surface_get_user_data(const_cast<wl_surface *>(surface))); - GHOST_ASSERT(win == GHOST_WindowWayland::from_surface_find(surface), - "Inconsistent window state, consider using \"from_surface_find\""); - return win; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Public WAYLAND Window Level Functions * * High Level Windowing Utilities. @@ -910,7 +884,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale() win->size_pending[1] = (win->size_pending[1] / scale_curr) * scale_next; win->scale = scale_next; - wl_surface_set_buffer_scale(this->surface(), scale_next); + wl_surface_set_buffer_scale(w->wl_surface, scale_next); changed = true; } @@ -946,22 +920,4 @@ bool GHOST_WindowWayland::outputs_leave(output_t *reg_output) return true; } -bool GHOST_WindowWayland::outputs_enter_wl(const wl_output *output) -{ - output_t *reg_output = m_system->output_find_by_wl(output); - if (!reg_output) { - return false; - } - return outputs_enter(reg_output); -} - -bool GHOST_WindowWayland::outputs_leave_wl(const wl_output *output) -{ - output_t *reg_output = m_system->output_find_by_wl(output); - if (!reg_output) { - return false; - } - return outputs_leave(reg_output); -} - /** \} */ diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index 1afad3b47b3..c754e4cd9e7 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -100,19 +100,6 @@ class GHOST_WindowWayland : public GHOST_Window { struct wl_surface *surface() const; const std::vector<output_t *> &outputs(); - /* WAYLAND query access. */ - - /** - * Use window find function when the window may have been closed. - * Typically this is needed when accessing surfaces outside WAYLAND handlers. - */ - static GHOST_WindowWayland *from_surface_find(const wl_surface *surface); - /** - * Use direct access when from WAYLAND handlers. - */ - static const GHOST_WindowWayland *from_surface(const wl_surface *surface); - static GHOST_WindowWayland *from_surface_mut(wl_surface *surface); - /* WAYLAND window-level functions. */ GHOST_TSuccess close(); @@ -124,8 +111,6 @@ class GHOST_WindowWayland : public GHOST_Window { bool outputs_enter(output_t *reg_output); bool outputs_leave(output_t *reg_output); - bool outputs_enter_wl(const struct wl_output *output); - bool outputs_leave_wl(const struct wl_output *output); bool outputs_changed_update_scale(); |