Skip to content

Commit

Permalink
VIDEO: adopt the _mouseCanUseGlobalState state from dearimgui backend…
Browse files Browse the repository at this point in the history
… code
  • Loading branch information
mgerhardy committed Jan 3, 2022
1 parent 63dcaa5 commit 17868bf
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/modules/ui/imgui/IMGUIApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,9 +692,9 @@ void IMGUIApp::beforeUI() {
io.MouseDown[2] = _mousePressed[2] || (mouseButtons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
_mousePressed[0] = _mousePressed[1] = _mousePressed[2] = false;

SDL_Window *mouseWindow = NULL;
if (isSingleWindowMode()) {
mouseWindow = (SDL_GetWindowFlags(_window) & SDL_WINDOW_INPUT_FOCUS) ? _window : NULL;
SDL_Window *mouseWindow = nullptr;
if (isSingleWindowMode() || (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) == 0) {
mouseWindow = (SDL_GetWindowFlags(_window) & SDL_WINDOW_INPUT_FOCUS) ? _window : nullptr;
} else {
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window
// is capturing)
Expand Down Expand Up @@ -726,13 +726,11 @@ void IMGUIApp::beforeUI() {
}
}

if (isSingleWindowMode()) {
io.MousePos = ImVec2((float)mouseXLocal, (float)mouseYLocal);
} else {
if (_mouseCanUseGlobalState) {
// Set Dear ImGui mouse position from OS position + get buttons. (this is the common behavior)
int mouseXGlobal, mouseYGlobal;
int mouseXGlobal = 0, mouseYGlobal = 0;
SDL_GetGlobalMouseState(&mouseXGlobal, &mouseYGlobal);
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != 0) {
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on
// the upper-left of the primary monitor)
io.MousePos = ImVec2((float)mouseXGlobal, (float)mouseYGlobal);
Expand All @@ -742,8 +740,23 @@ void IMGUIApp::beforeUI() {
// when straying out of bounds.
int windowX = 0, windowY = 0;
SDL_GetWindowPosition(mouseWindow, &windowX, &windowY);
int index = SDL_GetWindowDisplayIndex(mouseWindow);
if (index >= 0) {
SDL_Rect rect;
if (SDL_GetDisplayBounds(index, &rect) == 0) {
SDL_Point point;
point.x = mouseXGlobal;
point.y = mouseYGlobal;
if (!SDL_PointInRect(&point, &rect)) {
windowX -= rect.x;
windowY -= rect.y;
}
}
}
io.MousePos = ImVec2((float)(mouseXGlobal - windowX), (float)(mouseYGlobal - windowY));
}
} else {
io.MousePos = ImVec2((float)mouseXLocal, (float)mouseYLocal);
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/modules/video/WindowedApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,20 @@ app::AppState WindowedApp::onInit() {
video::init(_windowDimension.x, _windowDimension.y, scaleFactor);
video::viewport(0, 0, _frameBufferDimension.x, _frameBufferDimension.y);

if (isSingleWindowMode()) {
_mouseCanUseGlobalState = false;
} else {
// Check and store if we are on a SDL backend that supports global mouse position
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
const char *sdlBackend = SDL_GetCurrentVideoDriver();
const char *globalMouseWhitelist[] = {"windows", "cocoa", "x11", "DIVE", "VMAN"};
for (int n = 0; n < lengthof(globalMouseWhitelist); ++n) {
if (strncmp(sdlBackend, globalMouseWhitelist[n], strlen(globalMouseWhitelist[n])) == 0) {
_mouseCanUseGlobalState = true;
}
}
}

video_trace_init();

return state;
Expand Down
1 change: 1 addition & 0 deletions src/modules/video/WindowedApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class WindowedApp: public app::App, public io::IEventObserver {
* Will block the event queue if the window is minimized of hidden
*/
bool _powerSaveMode = true;
bool _mouseCanUseGlobalState = false;

util::KeyBindingHandler _keybindingHandler;
/**
Expand Down

0 comments on commit 17868bf

Please sign in to comment.