Skip to content

Commit 982b515

Browse files
committed
macOS: When toggling in the quick access terminal move it to the currently active screen
Fixes #9003
1 parent 9a6cf49 commit 982b515

File tree

11 files changed

+69
-22
lines changed

11 files changed

+69
-22
lines changed

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ Detailed list of changes
155155
it was last active on, after full screening some application causes the quick
156156
access terminal to appear on the old space (:iss:`8740`)
157157

158+
- macOS: When toggling open the quick access terminal move it to the currently
159+
active monitor (the monitor with the mouse pointer on it) (:iss:`9003`)
160+
158161
- macOS: Fix closing an OS Window when another OS Window is minimized causing
159162
the minimized window to be un-minimized (:iss:`8913`)
160163

glfw/cocoa_window.m

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,6 +1971,40 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
19711971
return NSScreen.mainScreen;
19721972
}
19731973

1974+
static NSScreen*
1975+
active_screen(void) {
1976+
NSPoint mouseLocation = [NSEvent mouseLocation];
1977+
NSArray<NSScreen *> *screens = [NSScreen screens];
1978+
for (NSScreen *screen in screens) {
1979+
if (NSPointInRect(mouseLocation, [screen frame])) {
1980+
return screen;
1981+
}
1982+
}
1983+
// As a fallback, return the main screen
1984+
return [NSScreen mainScreen];
1985+
}
1986+
1987+
static bool
1988+
is_same_screen(NSScreen *screenA, NSScreen * screenB) {
1989+
if (screenA == screenB) return true;
1990+
NSDictionary<NSDeviceDescriptionKey, id> *deviceDescriptionA = [screenA deviceDescription];
1991+
NSDictionary<NSDeviceDescriptionKey, id> *deviceDescriptionB = [screenB deviceDescription];
1992+
NSNumber *screenNumberA = deviceDescriptionA[@"NSScreenNumber"];
1993+
NSNumber *screenNumberB = deviceDescriptionB[@"NSScreenNumber"];
1994+
return [screenNumberA isEqualToNumber:screenNumberB];
1995+
}
1996+
1997+
static void
1998+
move_window_to_screen(_GLFWwindow *window, NSScreen *target) {
1999+
NSRect screenFrame = [target visibleFrame];
2000+
NSRect windowFrame = [window->ns.object frame];
2001+
CGFloat newX = NSMidX(screenFrame) - (windowFrame.size.width / 2.0);
2002+
CGFloat newY = NSMidY(screenFrame) - (windowFrame.size.height / 2.0);
2003+
NSRect newWindowFrame = NSMakeRect(newX, newY, windowFrame.size.width, windowFrame.size.height);
2004+
[window->ns.object setFrame:newWindowFrame display:NO animate:NO];
2005+
if (window->ns.layer_shell.is_active) _glfwPlatformSetLayerShellConfig(window, NULL);
2006+
}
2007+
19742008
const GLFWLayerShellConfig*
19752009
_glfwPlatformGetLayerShellConfig(_GLFWwindow *window) {
19762010
return &window->ns.layer_shell.config;
@@ -2257,10 +2291,18 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
22572291
}
22582292
}
22592293

2260-
void _glfwPlatformShowWindow(_GLFWwindow* window)
2294+
void _glfwPlatformShowWindow(_GLFWwindow* window, bool move_to_active_screen)
22612295
{
22622296
const bool is_background = window->ns.layer_shell.is_active && window->ns.layer_shell.config.type == GLFW_LAYER_SHELL_BACKGROUND;
22632297
NSWindow *nw = window->ns.object;
2298+
if (move_to_active_screen) {
2299+
NSScreen *current_screen = screen_for_window_center(window);
2300+
NSScreen *target_screen = active_screen();
2301+
if (!is_same_screen(current_screen, target_screen)) {
2302+
debug_rendering("Moving OS window %llu to active screen\n", window->id);
2303+
move_window_to_screen(window, target_screen);
2304+
}
2305+
}
22642306
if (is_background) {
22652307
[nw orderBack:nil];
22662308
} else {

glfw/glfw3.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3579,7 +3579,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
35793579
*
35803580
* @ingroup window
35813581
*/
3582-
GLFWAPI void glfwShowWindow(GLFWwindow* window);
3582+
GLFWAPI void glfwShowWindow(GLFWwindow* window, bool move_to_active_screen);
35833583

35843584
/*! @brief Hides the specified window.
35853585
*

glfw/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ monotonic_t _glfwPlatformGetDoubleClickInterval(_GLFWwindow* window);
740740
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
741741
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
742742
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
743-
void _glfwPlatformShowWindow(_GLFWwindow* window);
743+
void _glfwPlatformShowWindow(_GLFWwindow* window, bool move_to_active_screen);
744744
void _glfwPlatformHideWindow(_GLFWwindow* window);
745745
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
746746
int _glfwPlatformWindowBell(_GLFWwindow* window);

glfw/window.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G
279279
{
280280
if (wndconfig.visible)
281281
{
282-
_glfwPlatformShowWindow(window);
282+
_glfwPlatformShowWindow(window, false);
283283
#ifndef _GLFW_WAYLAND
284284
if (wndconfig.focused)
285285
_glfwPlatformFocusWindow(window);
@@ -855,7 +855,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
855855
_glfwPlatformMaximizeWindow(window);
856856
}
857857

858-
GLFWAPI void glfwShowWindow(GLFWwindow* handle)
858+
GLFWAPI void glfwShowWindow(GLFWwindow* handle, bool move_to_active_screen)
859859
{
860860
_GLFWwindow* window = (_GLFWwindow*) handle;
861861
assert(window != NULL);
@@ -865,7 +865,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
865865
if (window->monitor)
866866
return;
867867

868-
_glfwPlatformShowWindow(window);
868+
_glfwPlatformShowWindow(window, move_to_active_screen);
869869

870870
#ifndef _GLFW_WAYLAND
871871
if (window->focusOnShow)

glfw/wl_window.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1756,7 +1756,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
17561756
}
17571757
}
17581758

1759-
void _glfwPlatformShowWindow(_GLFWwindow* window)
1759+
void _glfwPlatformShowWindow(_GLFWwindow* window, bool move_to_active_screen UNUSED)
17601760
{
17611761
if (!window->wl.visible) {
17621762
if (!window->wl.created) {

glfw/x11_window.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconf
20612061

20622062
if (window->monitor)
20632063
{
2064-
_glfwPlatformShowWindow(window);
2064+
_glfwPlatformShowWindow(window, false);
20652065
updateWindowMode(window);
20662066
acquireMonitor(window);
20672067
}
@@ -2458,7 +2458,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
24582458
XFlush(_glfw.x11.display);
24592459
}
24602460

2461-
void _glfwPlatformShowWindow(_GLFWwindow* window)
2461+
void _glfwPlatformShowWindow(_GLFWwindow* window, bool move_to_active_screen UNUSED)
24622462
{
24632463
if (_glfwPlatformWindowVisible(window))
24642464
return;

kitty/boss.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ def peer_message_received(self, msg_bytes: bytes, peer_id: int, is_remote_contro
957957

958958
def quick_access_terminal_invoked(self) -> None:
959959
for os_window_id in self.os_window_map:
960-
toggle_os_window_visibility(os_window_id)
960+
toggle_os_window_visibility(os_window_id, move_to_active_screen=True)
961961

962962
def handle_remote_cmd(self, cmd: memoryview, window: Window | None = None) -> None:
963963
response = self._handle_remote_command(cmd, window)

kitty/fast_data_types.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1719,7 +1719,7 @@ def get_docs_ref_map() -> bytes: ...
17191719
def set_clipboard_data_types(ct: int, mime_types: Tuple[str, ...]) -> None: ...
17201720
def get_clipboard_mime(ct: int, mime: Optional[str], callback: Callable[[bytes], None]) -> None: ...
17211721
def run_with_activation_token(func: Callable[[str], None]) -> bool: ...
1722-
def toggle_os_window_visibility(os_window_id: int, visible: Literal[True, False] = ...) -> bool: ...
1722+
def toggle_os_window_visibility(os_window_id: int, visible: bool | Literal[-1] = -1, move_to_active_screen: bool = False) -> bool: ...
17231723
def parse_cli_from_spec(args: list[str], names_map: dict[str, OptionDict], defval_map: dict[str, Any]) -> tuple[dict[str, tuple[Any, bool]], list[str]]: ...
17241724
def layer_shell_config_for_os_window(os_window_id: int) -> dict[str, Any] | None: ...
17251725
def set_layer_shell_config(os_window_id: int, cfg: LayerShellConfig) -> bool: ...

kitty/glfw-wrapper.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)