GHOST/Wayland: workaround inability to access window position

Wayland doesn't support accessing the position making functionality that
would map events to other windows fail, sometimes considering windows
overlapping when they weren't (as all window positions were zeroed).

Disable dragging between windows when accessing the window the position
isn't supported.
This commit is contained in:
Campbell Barton 2022-06-16 15:16:04 +10:00
parent a17f74ab34
commit 65b1b1cd34
8 changed files with 37 additions and 1 deletions

View File

@ -906,6 +906,11 @@ extern int GHOST_UseNativePixels(void);
*/
extern int GHOST_SupportsCursorWarp(void);
/**
* Support positioning windows (when false `wmWindow.x,y` are meaningless).
*/
extern int GHOST_SupportsWindowPosition(void);
/**
* Assign the callback which generates a back-trace (may be NULL).
*/

View File

@ -312,6 +312,11 @@ class GHOST_ISystem {
*/
virtual bool supportsCursorWarp() = 0;
/**
* Return true getting/setting the window position is supported.
*/
virtual bool supportsWindowPosition() = 0;
/**
* Focus window after opening, or put them in the background.
*/

View File

@ -835,6 +835,12 @@ int GHOST_SupportsCursorWarp(void)
return system->supportsCursorWarp();
}
int GHOST_SupportsWindowPosition(void)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->supportsWindowPosition();
}
void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
{
GHOST_ISystem::setBacktraceFn(backtrace_fn);

View File

@ -395,6 +395,11 @@ bool GHOST_System::supportsCursorWarp()
return true;
}
bool GHOST_System::supportsWindowPosition()
{
return true;
}
void GHOST_System::initDebug(GHOST_Debug debug)
{
m_is_debug_enabled = debug.flags & GHOST_kDebugDefault;

View File

@ -152,6 +152,7 @@ class GHOST_System : public GHOST_ISystem {
bool m_nativePixel;
bool supportsCursorWarp(void);
bool supportsWindowPosition(void);
/**
* Focus window after opening, or put them in the background.

View File

@ -2682,6 +2682,14 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(bool visible)
bool GHOST_SystemWayland::supportsCursorWarp()
{
/* WAYLAND doesn't support setting the cursor position directly,
* this is an intentional choice, forcing us to use a software cursor in this case. */
return false;
}
bool GHOST_SystemWayland::supportsWindowPosition()
{
/* WAYLAND doesn't support accessing the window position. */
return false;
}

View File

@ -125,6 +125,7 @@ class GHOST_SystemWayland : public GHOST_System {
GHOST_TSuccess setCursorVisibility(bool visible);
bool supportsCursorWarp();
bool supportsWindowPosition();
GHOST_TSuccess setCursorGrab(const GHOST_TGrabCursorMode mode,
const GHOST_TGrabCursorMode mode_current,

View File

@ -4942,7 +4942,11 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
/* Imperfect but probably usable... draw/enable drags to other windows. */
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
{
int mval[2] = {event->xy[0], event->xy[1]};
/* If GHOST doesn't support window positioning, don't use this feature at all. */
const static int8_t supports_window_position = GHOST_SupportsWindowPosition();
if (!supports_window_position) {
return nullptr;
}
if (wm->windows.first == wm->windows.last) {
return nullptr;
@ -4951,6 +4955,7 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
/* In order to use window size and mouse position (pixels), we have to use a WM function. */
/* Check if outside, include top window bar. */
int mval[2] = {event->xy[0], event->xy[1]};
if (mval[0] < 0 || mval[1] < 0 || mval[0] > WM_window_pixels_x(win) ||
mval[1] > WM_window_pixels_y(win) + 30) {
/* Let's skip windows having modal handlers now. */