GHOST: get/set cursor position now uses client instead of screen coords
Use client (window) relative coordinates for cursor position access, this only moves the conversion from window-manager into GHOST, (no functional changes). This is needed for fix a bug in GHOST/Wayland which doesn't support accessing absolute cursor coordinates & the window is needed to properly access the cursor coordinates. As it happens every caller to GHOST_GetCursorPosition was already making the values window-relative, so there is little benefit in attempting to workaround the problem on the Wayland side. If needed the screen-space versions of functions can be exposed again.
This commit is contained in:
parent
df40e9d0aa
commit
6bd2c6789b
|
@ -383,27 +383,28 @@ extern bool GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle);
|
|||
extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, bool visible);
|
||||
|
||||
/**
|
||||
* Returns the current location of the cursor (location in screen coordinates)
|
||||
* Returns the current location of the cursor (location in client relative coordinates)
|
||||
* \param systemhandle: The handle to the system.
|
||||
* \param x: The x-coordinate of the cursor.
|
||||
* \param y: The y-coordinate of the cursor.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,
|
||||
int32_t *x,
|
||||
int32_t *y);
|
||||
|
||||
GHOST_TSuccess GHOST_GetCursorPosition(const GHOST_SystemHandle systemhandle,
|
||||
const GHOST_WindowHandle windowhandle,
|
||||
int32_t *x,
|
||||
int32_t *y);
|
||||
/**
|
||||
* Updates the location of the cursor (location in screen coordinates).
|
||||
* Updates the location of the cursor (location in client relative coordinates).
|
||||
* Not all operating systems allow the cursor to be moved (without the input device being moved).
|
||||
* \param systemhandle: The handle to the system.
|
||||
* \param x: The x-coordinate of the cursor.
|
||||
* \param y: The y-coordinate of the cursor.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
||||
int32_t x,
|
||||
int32_t y);
|
||||
GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
||||
GHOST_WindowHandle windowhandle,
|
||||
int32_t x,
|
||||
int32_t y);
|
||||
|
||||
void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
|
||||
GHOST_TGrabCursorMode *r_mode,
|
||||
|
|
|
@ -364,6 +364,25 @@ class GHOST_ISystem {
|
|||
* Cursor management functionality
|
||||
***************************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns the current location of the cursor (location in window coordinates)
|
||||
* \param x: The x-coordinate of the cursor.
|
||||
* \param y: The y-coordinate of the cursor.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess getCursorPositionClientRelative(const GHOST_IWindow *window,
|
||||
int32_t &x,
|
||||
int32_t &y) const = 0;
|
||||
/**
|
||||
* Updates the location of the cursor (location in window coordinates).
|
||||
* \param x: The x-coordinate of the cursor.
|
||||
* \param y: The y-coordinate of the cursor.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorPositionClientRelative(GHOST_IWindow *window,
|
||||
int32_t x,
|
||||
int32_t y) = 0;
|
||||
|
||||
/**
|
||||
* Returns the current location of the cursor (location in screen coordinates)
|
||||
* \param x: The x-coordinate of the cursor.
|
||||
|
|
|
@ -348,19 +348,49 @@ GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, bool v
|
|||
return window->setCursorVisibility(visible);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, int32_t *x, int32_t *y)
|
||||
/* Unused, can expose again if needed although WAYLAND
|
||||
* can only properly use client relative coordinates, so leave disabled if possible. */
|
||||
#if 0
|
||||
GHOST_TSuccess GHOST_GetCursorPositionScreenCoords(GHOST_SystemHandle systemhandle,
|
||||
int32_t *x,
|
||||
int32_t *y)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
|
||||
return system->getCursorPosition(*x, *y);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, int32_t x, int32_t y)
|
||||
GHOST_TSuccess GHOST_SetCursorPositionScreenCoords(GHOST_SystemHandle systemhandle,
|
||||
int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
|
||||
return system->setCursorPosition(x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
GHOST_TSuccess GHOST_GetCursorPosition(const GHOST_SystemHandle systemhandle,
|
||||
const GHOST_WindowHandle windowhandle,
|
||||
int32_t *x,
|
||||
int32_t *y)
|
||||
{
|
||||
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
|
||||
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
|
||||
|
||||
return system->getCursorPositionClientRelative(window, *x, *y);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
||||
GHOST_WindowHandle windowhandle,
|
||||
int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
|
||||
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
|
||||
|
||||
return system->setCursorPositionClientRelative(window, x, y);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
||||
GHOST_TGrabCursorMode mode,
|
||||
|
|
|
@ -260,6 +260,29 @@ GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent *event)
|
|||
return success;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::getCursorPositionClientRelative(const GHOST_IWindow *window,
|
||||
int32_t &x,
|
||||
int32_t &y) const
|
||||
{
|
||||
/* Sub-classes that can implement this directly should do so. */
|
||||
int32_t screen_x, screen_y;
|
||||
GHOST_TSuccess success = getCursorPosition(screen_x, screen_y);
|
||||
if (success == GHOST_kSuccess) {
|
||||
window->screenToClient(screen_x, screen_y, x, y);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::setCursorPositionClientRelative(GHOST_IWindow *window,
|
||||
int32_t x,
|
||||
int32_t y)
|
||||
{
|
||||
/* Sub-classes that can implement this directly should do so. */
|
||||
int32_t screen_x, screen_y;
|
||||
window->clientToScreen(x, y, screen_x, screen_y);
|
||||
return setCursorPosition(screen_x, screen_y);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKey mask, bool &isDown) const
|
||||
{
|
||||
GHOST_ModifierKeys keys;
|
||||
|
|
|
@ -203,6 +203,17 @@ class GHOST_System : public GHOST_ISystem {
|
|||
* Cursor management functionality
|
||||
***************************************************************************************/
|
||||
|
||||
/* Client relative functions use a default implementation
|
||||
* that converts from screen-coordinates to client coordinates.
|
||||
* Implementations may override. */
|
||||
|
||||
GHOST_TSuccess getCursorPositionClientRelative(const GHOST_IWindow *window,
|
||||
int32_t &x,
|
||||
int32_t &y) const override;
|
||||
GHOST_TSuccess setCursorPositionClientRelative(GHOST_IWindow *window,
|
||||
int32_t x,
|
||||
int32_t y) override;
|
||||
|
||||
/**
|
||||
* Inherited from GHOST_ISystem but left pure virtual
|
||||
* <pre>
|
||||
|
|
|
@ -231,8 +231,8 @@ void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
|
|||
GHOST_TAxisFlag mode_axis = GHOST_kAxisX | GHOST_kAxisY;
|
||||
|
||||
if (bounds) {
|
||||
wm_cursor_position_to_ghost(win, &bounds[0], &bounds[1]);
|
||||
wm_cursor_position_to_ghost(win, &bounds[2], &bounds[3]);
|
||||
wm_cursor_position_to_ghost_screen_coords(win, &bounds[0], &bounds[1]);
|
||||
wm_cursor_position_to_ghost_screen_coords(win, &bounds[2], &bounds[3]);
|
||||
}
|
||||
|
||||
if (hide) {
|
||||
|
@ -266,7 +266,7 @@ void WM_cursor_grab_disable(wmWindow *win, const int mouse_ungrab_xy[2])
|
|||
if (win && win->ghostwin) {
|
||||
if (mouse_ungrab_xy) {
|
||||
int mouse_xy[2] = {mouse_ungrab_xy[0], mouse_ungrab_xy[1]};
|
||||
wm_cursor_position_to_ghost(win, &mouse_xy[0], &mouse_xy[1]);
|
||||
wm_cursor_position_to_ghost_screen_coords(win, &mouse_xy[0], &mouse_xy[1]);
|
||||
GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, GHOST_kAxisNone, NULL, mouse_xy);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1217,8 +1217,7 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
|
|||
GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
|
||||
int cx, cy, sizex, sizey, inside_window;
|
||||
|
||||
GHOST_GetCursorPosition(g_WS.ghost_system, &cx, &cy);
|
||||
GHOST_ScreenToClient(g_WS.ghost_window, cx, cy, &cx, &cy);
|
||||
GHOST_GetCursorPosition(g_WS.ghost_system, g_WS.ghost_window, &cx, &cy);
|
||||
playanim_window_get_size(&sizex, &sizey);
|
||||
|
||||
inside_window = (cx >= 0 && cx < sizex && cy >= 0 && cy <= sizey);
|
||||
|
@ -1267,15 +1266,15 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
|
|||
* however the API currently doesn't support this. */
|
||||
{
|
||||
int x_test, y_test;
|
||||
GHOST_GetCursorPosition(g_WS.ghost_system, &x_test, &y_test);
|
||||
if (x_test != cd->x || y_test != cd->y) {
|
||||
GHOST_GetCursorPosition(g_WS.ghost_system, g_WS.ghost_window, &cx, &cy);
|
||||
GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &x_test, &y_test);
|
||||
|
||||
if (cx != x_test || cy != y_test) {
|
||||
/* we're not the last event... skipping */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &cx, &cy);
|
||||
|
||||
tag_change_frame(ps, cx);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -920,25 +920,33 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
|
||||
/* ************ events *************** */
|
||||
|
||||
void wm_cursor_position_from_ghost(wmWindow *win, int *x, int *y)
|
||||
void wm_cursor_position_from_ghost_client_coords(wmWindow *win, int *x, int *y)
|
||||
{
|
||||
float fac = GHOST_GetNativePixelSize(win->ghostwin);
|
||||
|
||||
GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
|
||||
*x *= fac;
|
||||
|
||||
*y = (win->sizey - 1) - *y;
|
||||
*y *= fac;
|
||||
}
|
||||
|
||||
void wm_cursor_position_to_ghost(wmWindow *win, int *x, int *y)
|
||||
void wm_cursor_position_to_ghost_client_coords(wmWindow *win, int *x, int *y)
|
||||
{
|
||||
float fac = GHOST_GetNativePixelSize(win->ghostwin);
|
||||
|
||||
*x /= fac;
|
||||
*y /= fac;
|
||||
*y = win->sizey - *y - 1;
|
||||
}
|
||||
|
||||
void wm_cursor_position_from_ghost_screen_coords(wmWindow *win, int *x, int *y)
|
||||
{
|
||||
GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
|
||||
wm_cursor_position_from_ghost_client_coords(win, x, y);
|
||||
}
|
||||
|
||||
void wm_cursor_position_to_ghost_screen_coords(wmWindow *win, int *x, int *y)
|
||||
{
|
||||
wm_cursor_position_to_ghost_client_coords(win, x, y);
|
||||
GHOST_ClientToScreen(win->ghostwin, *x, *y, x, y);
|
||||
}
|
||||
|
||||
|
@ -949,8 +957,8 @@ void wm_cursor_position_get(wmWindow *win, int *r_x, int *r_y)
|
|||
*r_y = win->eventstate->xy[1];
|
||||
return;
|
||||
}
|
||||
GHOST_GetCursorPosition(g_system, r_x, r_y);
|
||||
wm_cursor_position_from_ghost(win, r_x, r_y);
|
||||
GHOST_GetCursorPosition(g_system, win->ghostwin, r_x, r_y);
|
||||
wm_cursor_position_from_ghost_client_coords(win, r_x, r_y);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
|
@ -1418,14 +1426,14 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
|
|||
case GHOST_kEventTrackpad: {
|
||||
GHOST_TEventTrackpadData *pd = data;
|
||||
|
||||
wm_cursor_position_from_ghost(win, &pd->x, &pd->y);
|
||||
wm_cursor_position_from_ghost_screen_coords(win, &pd->x, &pd->y);
|
||||
wm_event_add_ghostevent(wm, win, type, data);
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventCursorMove: {
|
||||
GHOST_TEventCursorData *cd = data;
|
||||
|
||||
wm_cursor_position_from_ghost(win, &cd->x, &cd->y);
|
||||
wm_cursor_position_from_ghost_screen_coords(win, &cd->x, &cd->y);
|
||||
wm_event_add_ghostevent(wm, win, type, data);
|
||||
break;
|
||||
}
|
||||
|
@ -1866,7 +1874,7 @@ wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mv
|
|||
{
|
||||
int tmp[2];
|
||||
copy_v2_v2_int(tmp, mval);
|
||||
wm_cursor_position_to_ghost(win, &tmp[0], &tmp[1]);
|
||||
wm_cursor_position_to_ghost_screen_coords(win, &tmp[0], &tmp[1]);
|
||||
|
||||
GHOST_WindowHandle ghostwin = GHOST_GetWindowUnderCursor(g_system, tmp[0], tmp[1]);
|
||||
|
||||
|
@ -1875,7 +1883,7 @@ wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mv
|
|||
}
|
||||
|
||||
wmWindow *win_other = GHOST_GetWindowUserData(ghostwin);
|
||||
wm_cursor_position_from_ghost(win_other, &tmp[0], &tmp[1]);
|
||||
wm_cursor_position_from_ghost_screen_coords(win_other, &tmp[0], &tmp[1]);
|
||||
copy_v2_v2_int(r_mval, tmp);
|
||||
return win_other;
|
||||
}
|
||||
|
@ -2015,8 +2023,8 @@ void WM_cursor_warp(wmWindow *win, int x, int y)
|
|||
if (win && win->ghostwin) {
|
||||
int oldx = x, oldy = y;
|
||||
|
||||
wm_cursor_position_to_ghost(win, &x, &y);
|
||||
GHOST_SetCursorPosition(g_system, x, y);
|
||||
wm_cursor_position_to_ghost_client_coords(win, &x, &y);
|
||||
GHOST_SetCursorPosition(g_system, win->ghostwin, x, y);
|
||||
|
||||
win->eventstate->prev_xy[0] = oldx;
|
||||
win->eventstate->prev_xy[1] = oldy;
|
||||
|
|
|
@ -100,8 +100,11 @@ void wm_window_set_swap_interval(wmWindow *win, int interval);
|
|||
bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut);
|
||||
|
||||
void wm_cursor_position_get(wmWindow *win, int *r_x, int *r_y);
|
||||
void wm_cursor_position_from_ghost(wmWindow *win, int *r_x, int *r_y);
|
||||
void wm_cursor_position_to_ghost(wmWindow *win, int *x, int *y);
|
||||
void wm_cursor_position_from_ghost_screen_coords(wmWindow *win, int *r_x, int *r_y);
|
||||
void wm_cursor_position_to_ghost_screen_coords(wmWindow *win, int *x, int *y);
|
||||
|
||||
void wm_cursor_position_from_ghost_client_coords(wmWindow *win, int *x, int *y);
|
||||
void wm_cursor_position_to_ghost_client_coords(wmWindow *win, int *x, int *y);
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
void wm_window_IME_begin(wmWindow *win, int x, int y, int w, int h, bool complete);
|
||||
|
|
Loading…
Reference in New Issue