diff options
-rw-r--r-- | intern/ghost/GHOST_C-api.h | 10 | ||||
-rw-r--r-- | intern/ghost/GHOST_ISystem.h | 8 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_C-api.cpp | 10 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_System.cpp | 19 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_System.h | 8 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.h | 8 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 14 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemNULL.h | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_eyedropper.c | 3 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 57 |
13 files changed, 100 insertions, 57 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 441c7315f1a..18439350238 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -249,6 +249,16 @@ extern GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle); */ extern int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle); +/** + * Get the Window under the cursor. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * @return The window under the cursor or nullptr in none. + */ +extern GHOST_WindowHandle GHOST_GetWindowUnderCursor(GHOST_SystemHandle systemhandle, + int32_t x, + int32_t y); + /*************************************************************************************** * Event management functionality ***************************************************************************************/ diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 837ec25d0f8..a33879522f4 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -309,6 +309,14 @@ class GHOST_ISystem { */ virtual void useWindowFocus(const bool use_focus) = 0; + /** + * Get the Window under the cursor. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * @return The window under the cursor or nullptr if none. + */ + virtual GHOST_IWindow *getWindowUnderCursor(int32_t x, int32_t y) = 0; + /*************************************************************************************** * Event management functionality ***************************************************************************************/ diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index a47d2468937..e3d01c24283 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -233,6 +233,16 @@ int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle) return (int)system->getFullScreen(); } +GHOST_WindowHandle GHOST_GetWindowUnderCursor(GHOST_SystemHandle systemhandle, + int32_t x, + int32_t y) +{ + GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; + GHOST_IWindow *window = system->getWindowUnderCursor(x, y); + + return (GHOST_WindowHandle)window; +} + bool GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, bool waitForEvent) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index e9c63502f66..3df85e18bc7 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -189,6 +189,25 @@ bool GHOST_System::getFullScreen(void) return fullScreen; } +GHOST_IWindow *GHOST_System::getWindowUnderCursor(int32_t x, int32_t y) +{ + /* TODO: This solution should follow the order of the activated windows (Z-order). + * It is imperfect but usable in most cases. */ + for (GHOST_IWindow *iwindow : m_windowManager->getWindows()) { + if (iwindow->getState() == GHOST_kWindowStateMinimized) { + continue; + } + + GHOST_Rect bounds; + iwindow->getClientBounds(bounds); + if (bounds.isInside(x, y)) { + return iwindow; + } + } + + return NULL; +} + void GHOST_System::dispatchEvents() { #ifdef WITH_INPUT_NDOF diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index 8602dd94e8c..0911b35f617 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -157,6 +157,14 @@ class GHOST_System : public GHOST_ISystem { void useWindowFocus(const bool use_focus); bool m_windowFocus; + /** + * Get the Window under the cursor. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * @return The window under the cursor or nullptr if none. + */ + GHOST_IWindow *getWindowUnderCursor(int32_t x, int32_t y); + /*************************************************************************************** * Event management functionality ***************************************************************************************/ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index a601d00561a..926d50b7942 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -109,6 +109,14 @@ class GHOST_SystemCocoa : public GHOST_System { */ GHOST_TSuccess disposeContext(GHOST_IContext *context); + /** + * Get the Window under the cursor. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * @return The window under the cursor or nullptr if none. + */ + GHOST_IWindow *getWindowUnderCursor(int32_t x, int32_t y); + /*************************************************************************************** * Event management functionality ***************************************************************************************/ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index d3248a826e6..f0db6b6fdfc 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -772,6 +772,20 @@ GHOST_TSuccess GHOST_SystemCocoa::disposeContext(GHOST_IContext *context) return GHOST_kSuccess; } +GHOST_IWindow *GHOST_SystemCocoa::getWindowUnderCursor(int32_t x, int32_t y) +{ + NSPoint scr_co = NSMakePoint(x, y); + + int windowNumberAtPoint = [NSWindow windowNumberAtPoint:scr_co belowWindowWithWindowNumber:0]; + NSWindow *nswindow = [NSApp windowWithWindowNumber:windowNumberAtPoint]; + + if (nswindow == nil) { + return nil; + } + + return m_windowManager->getWindowAssociatedWithOSWindow((void *)nswindow); +} + /** * \note : returns coordinates in Cocoa screen coordinates */ diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h index 7b92d1d13a1..48973a00573 100644 --- a/intern/ghost/intern/GHOST_SystemNULL.h +++ b/intern/ghost/intern/GHOST_SystemNULL.h @@ -114,4 +114,9 @@ class GHOST_SystemNULL : public GHOST_System { type, ((glSettings.flags & GHOST_glStereoVisual) != 0)); } + + GHOST_IWindow *getWindowUnderCursor(int32_t x, int32_t y) + { + return NULL; + } }; diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index e72381821e8..eaec1e249b7 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -147,8 +147,7 @@ void datadropper_win_area_find( *r_win = CTX_wm_window(C); *r_area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mval); if (*r_area == NULL) { - wmWindowManager *wm = CTX_wm_manager(C); - *r_win = WM_window_find_under_cursor(wm, NULL, *r_win, mval, r_mval); + *r_win = WM_window_find_under_cursor(*r_win, mval, r_mval); if (*r_win) { screen = WM_window_get_active_screen(*r_win); *r_area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, r_mval); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index a64948b5864..af84f6f99a9 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -3442,7 +3442,6 @@ ScrArea *ED_area_find_under_cursor(const bContext *C, int spacetype, const int x { bScreen *screen = CTX_wm_screen(C); wmWindow *win = CTX_wm_window(C); - wmWindowManager *wm = CTX_wm_manager(C); ScrArea *area = NULL; @@ -3454,8 +3453,8 @@ ScrArea *ED_area_find_under_cursor(const bContext *C, int spacetype, const int x if (!area) { /* Check all windows except the active one. */ int scr_pos[2]; - wmWindow *r_win = WM_window_find_under_cursor(wm, win, win, xy, scr_pos); - if (r_win) { + wmWindow *r_win = WM_window_find_under_cursor(win, xy, scr_pos); + if (r_win && r_win != win) { win = r_win; screen = WM_window_get_active_screen(win); area = BKE_screen_find_area_xy(screen, spacetype, scr_pos); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ef8aed4c664..2c2143f350a 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -127,11 +127,7 @@ void WM_reinit_gizmomap_all(struct Main *bmain); */ void WM_script_tag_reload(void); -wmWindow *WM_window_find_under_cursor(const wmWindowManager *wm, - const wmWindow *win_ignore, - const wmWindow *win, - const int mval[2], - int r_mval[2]); +wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mval[2]); void WM_window_pixel_sample_read(const wmWindowManager *wm, const wmWindow *win, const int pos[2], diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ee07e90f4de..fb5af920ff8 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -4667,8 +4667,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi } } - wmWindow *win_other = WM_window_find_under_cursor(wm, win, win, mval, mval); - if (win_other) { + wmWindow *win_other = WM_window_find_under_cursor(win, mval, mval); + if (win_other && win_other != win) { copy_v2_v2_int(event->xy, mval); return win_other; } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 242b8dc2968..e93ffe48aba 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1841,56 +1841,23 @@ bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut) /** \name Find Window Utility * \{ */ -static void wm_window_desktop_pos_get(const wmWindow *win, - const int screen_pos[2], - int r_desk_pos[2]) +wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mval[2]) { - /* To desktop space. */ - r_desk_pos[0] = screen_pos[0] + (int)(U.pixelsize * win->posx); - r_desk_pos[1] = screen_pos[1] + (int)(U.pixelsize * win->posy); -} - -static void wm_window_screen_pos_get(const wmWindow *win, - const int desktop_pos[2], - int r_scr_pos[2]) -{ - /* To window space. */ - r_scr_pos[0] = desktop_pos[0] - (int)(U.pixelsize * win->posx); - r_scr_pos[1] = desktop_pos[1] - (int)(U.pixelsize * win->posy); -} - -wmWindow *WM_window_find_under_cursor(const wmWindowManager *wm, - const wmWindow *win_ignore, - const wmWindow *win, - const int mval[2], - int r_mval[2]) -{ - int desk_pos[2]; - wm_window_desktop_pos_get(win, mval, desk_pos); - - /* TODO: This should follow the order of the activated windows. - * The current solution is imperfect but usable in most cases. */ - LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { - if (win_iter == win_ignore) { - continue; - } - - if (win_iter->windowstate == GHOST_kWindowStateMinimized) { - continue; - } - - int scr_pos[2]; - wm_window_screen_pos_get(win_iter, desk_pos, scr_pos); + int tmp[2]; + copy_v2_v2_int(tmp, mval); + wm_cursor_position_to_ghost(win, &tmp[0], &tmp[1]); - if (scr_pos[0] >= 0 && scr_pos[1] >= 0 && scr_pos[0] <= WM_window_pixels_x(win_iter) && - scr_pos[1] <= WM_window_pixels_y(win_iter)) { + GHOST_WindowHandle ghostwin = GHOST_GetWindowUnderCursor(g_system, tmp[0], tmp[1]); - copy_v2_v2_int(r_mval, scr_pos); - return win_iter; - } + if (!ghostwin) { + return NULL; } - return NULL; + wmWindow *r_win = GHOST_GetWindowUserData(ghostwin); + wm_cursor_position_from_ghost(r_win, &tmp[0], &tmp[1]); + copy_v2_v2_int(r_mval, tmp); + + return r_win; } void WM_window_pixel_sample_read(const wmWindowManager *wm, |