Commit: 827fa8176737f822b7f8d2354b05e59976c7101a Author: Campbell Barton Date: Tue Jun 14 15:54:17 2022 +1000 Branches: master https://developer.blender.org/rB827fa8176737f822b7f8d2354b05e59976c7101a
Fix cursor coordinates being quantized to the window scale in Wayland - Apply the scale before converting cursor coordinates to int. - Store sub-pixel cursor coordinates internally since this is what Wayland uses. - Use `wl_fixed_t xy[2]` for storing coordinates as it simplifies assigning/passing x/y coordinates to an argument / variable. - Also fix drag-and-drop coordinates which ignored scale. =================================================================== M intern/ghost/intern/GHOST_SystemWayland.cpp =================================================================== diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index dceff4ef2b4..9e683ceb437 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -107,7 +107,8 @@ struct data_offer_t { struct wl_data_offer *id; std::atomic<bool> in_use; struct { - int x, y; + /** Compatible with #input_t.xy coordinates. */ + wl_fixed_t xy[2]; } dnd; }; @@ -137,7 +138,23 @@ struct input_t { uint32_t pointer_serial; uint32_t tablet_serial; - int x, y; + + /** Use to check if the last cursor input was tablet or pointer. */ + uint32_t cursor_serial; + + /** + * High precision mouse coordinates (pointer or tablet). + * + * The following example converts these values to screen coordinates. + * \code{.cc} + * const wl_fixed_t scale = win->scale(); + * const int event_xy[2] = { + * wl_fixed_to_int(scale * input->xy[0]), + * wl_fixed_to_int(scale * input->xy[1]), + * }; + * \endocde + */ + wl_fixed_t xy[2]; GHOST_Buttons buttons; struct cursor_t cursor; @@ -544,18 +561,19 @@ static void relative_pointer_relative_motion( wl_fixed_t /*dy_unaccel*/) { input_t *input = static_cast<input_t *>(data); - - input->x += wl_fixed_to_int(dx); - input->y += wl_fixed_to_int(dy); - - GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>( - wl_surface_get_user_data(input->focus_pointer)); + GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(get_window(input->focus_pointer)); + if (win == nullptr) { + return; + } + const wl_fixed_t scale = win->scale(); + input->xy[0] += dx / scale; + input->xy[1] += dy / scale; input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), GHOST_kEventCursorMove, win, - input->x, - input->y, + wl_fixed_to_int(scale * input->xy[0]), + wl_fixed_to_int(scale * input->xy[1]), GHOST_TABLET_DATA_NONE)); } @@ -573,16 +591,20 @@ static void dnd_events(const input_t *const input, const GHOST_TEventType event) { /* NOTE: `input->data_offer_dnd_mutex` must already be locked. */ const uint64_t time = input->system->getMilliSeconds(); - GHOST_IWindow *const window = static_cast<GHOST_WindowWayland *>( + GHOST_WindowWayland *const win = static_cast<GHOST_WindowWayland *>( wl_surface_get_user_data(input->focus_dnd)); + if (!win) { + return; + } + const wl_fixed_t scale = win->scale(); + const int event_xy[2] = { + wl_fixed_to_int(scale * input->data_offer_dnd->dnd.xy[0]), + wl_fixed_to_int(scale * input->data_offer_dnd->dnd.xy[1]), + }; + for (const std::string &type : mime_preference_order) { - input->system->pushEvent(new GHOST_EventDragnDrop(time, - event, - mime_dnd.at(type), - window, - input->data_offer_dnd->dnd.x, - input->data_offer_dnd->dnd.y, - nullptr)); + input->system->pushEvent(new GHOST_EventDragnDrop( + time, event, mime_dnd.at(type), win, event_xy[0], event_xy[1], nullptr)); } } @@ -759,8 +781,8 @@ static void data_device_enter(void *data, data_offer_t *data_offer = input->data_offer_dnd; data_offer->in_use.store(true); - data_offer->dnd.x = wl_fixed_to_int(x); - data_offer->dnd.y = wl_fixed_to_int(y); + data_offer->dnd.xy[0] = x; + data_offer->dnd.xy[1] = y; wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | @@ -799,8 +821,9 @@ static void data_device_motion(void *data, input_t *input = static_cast<input_t *>(data); std::lock_guard lock{input->data_offer_dnd_mutex}; - input->data_offer_dnd->dnd.x = wl_fixed_to_int(x); - input->data_offer_dnd->dnd.y = wl_fixed_to_int(y); + input->data_offer_dnd->dnd.xy[0] = x; + input->data_offer_dnd->dnd.xy[1] = y; + dnd_events(input, GHOST_kEventDraggingUpdated); } @@ -820,8 +843,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic data_offer_t *data_offer, wl_surface *surface, const std::string mime_receive) { - const int x = data_offer->dnd.x; - const int y = data_offer->dnd.y; + const wl_fixed_t *xy = data_offer->dnd.xy; const std::string data = read_pipe(data_offer, mime_receive, nullptr); @@ -863,12 +885,14 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic flist->strings[i] = static_cast<uint8_t *>(malloc((uris[i].size() + 1) * sizeof(uint8_t))); memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1); } + + const wl_fixed_t scale = win->scale(); system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(), GHOST_kEventDraggingDropDone, GHOST_kDragnDropTypeFilenames, win, - x, - y, + wl_fixed_to_int(scale * xy[0]), + wl_fixed_to_int(scale * xy[1]), flist)); } else if (mime_receive == mime_text_plain || mime_receive == mime_text_utf8) { @@ -1052,17 +1076,19 @@ static void pointer_enter(void *data, input_t *input = static_cast<input_t *>(data); input->pointer_serial = serial; - input->x = win->scale() * wl_fixed_to_int(surface_x); - input->y = win->scale() * wl_fixed_to_int(surface_y); + input->cursor_serial = serial; + input->xy[0] = surface_x; + input->xy[1] = surface_y; input->focus_pointer = surface; win->setCursorShape(win->getCursorShape()); + const wl_fixed_t scale = win->scale(); input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), GHOST_kEventCursorMove, static_cast<GHOST_WindowWayland *>(win), - input->x, - input->y, + wl_fixed_to_int(scale * input->xy[0]), + wl_fixed_to_int(scale * input->xy[1]), GHOST_TABLET_DATA_NONE)); } @@ -1095,14 +1121,15 @@ static void pointer_motion(void *data, return; } - input->x = win->scale() * wl_fixed_to_int(surface_x); - input->y = win->scale() * wl_fixed_to_int(surface_y); + input->xy[0] = surface_x; + input->xy[1] = surface_y; + const wl_fixed_t scale = win->scale(); input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), GHOST_kEventCursorMove, win, - input->x, - input->y, + wl_fixed_to_int(scale * input->xy[0]), + wl_fixed_to_int(scale * input->xy[1]), GHOST_TABLET_DATA_NONE)); } @@ -1253,6 +1280,8 @@ static void tablet_tool_proximity_in(void *data, input->focus_tablet = surface; input->tablet_serial = serial; + input->cursor_serial = serial; + input->data_source_serial = serial; /* Update #GHOST_TabletData. */ @@ -1333,14 +1362,15 @@ static void tablet_tool_motion(void *data, return; } - input->x = win->scale() * wl_fixed_to_int(x); - input->y = win->scale() * wl_fixed_to_int(y); + input->xy[0] = x; + input->xy[1] = y; + const wl_fixed_t scale = win->scale(); input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), GHOST_kEventCursorMove, win, - input->x, - input->y, + wl_fixed_to_int(scale * input->xy[0]), + wl_fixed_to_int(scale * input->xy[1]), tool_input->data)); } @@ -2116,13 +2146,26 @@ uint8_t GHOST_SystemWayland::getNumDisplays() const GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) const { - if (d->inputs.empty() || - (d->inputs[0]->focus_pointer == nullptr && d->inputs[0]->focus_tablet == nullptr)) { + if (d->inputs.empty()) { + return GHOST_kFailure; + } + + input_t *input = d->inputs[0]; + struct wl_surface *surface = nullptr; + if (input->pointer_serial == input->cursor_serial) { + surface = input->focus_pointer; + } + else if (input->tablet_serial == input->cursor_serial) { + surface = input->focus_tablet; + } + if (!surface) { return GHOST_kFailure; } - x = d->inputs[0]->x; - y = d->inputs[0]->y; + GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface)); + const wl_fixed_t scale = win->scale(); + x = wl_fixed_to_int(scale * input->xy[0]); + y = wl_fixed_to_int(scale * input->xy[1]); return GHOST_kSuccess; } @@ -2556,30 +2599,36 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo if (mode_current == GHOST_kGrabWr @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs