Skip to content

Commit ea34b7a

Browse files
authored
fix(Window Management): Next/Previous Desktop do not work (#926)
This commit fixes the issue that when the current desktop contains more than 1 windows, moving the focused window via `NextDesktop` and `PreviousDesktop` won't work. How? By adding 2 missing `sleep()` functions: 1. https://github.com/ianyh/Silica/blob/b91a18dbb822e99ce6b487d1cb4841e863139b2a/Silica/Sources/SIWindow.m#L242 2. https://github.com/ianyh/Silica/blob/b91a18dbb822e99ce6b487d1cb4841e863139b2a/Silica/Sources/SIWindow.m#L249 Also, this commit improves the implementation by resetting the mouse position. `NextDesktop` and `PreviousDesktop` are implemented by emulating mouse and keyboard events, draging the focused window and switching to the corresponding desktop. To make a window draggable, we have to move the mouse to the window's traffic light area. It is disturbing to not move the mouse back so this commit implements it.
1 parent ce94543 commit ea34b7a

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

  • docs/content.en/docs/release-notes
  • src-tauri/src/extension/built_in/window_management/backend

docs/content.en/docs/release-notes/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ fix: automatic update of service list #913
2424
fix: duplicate chat content #916
2525
fix: resolve pinned window shortcut not working #917
2626
fix: WM ext does not work when operating focused win from another display #919
27+
fix(Window Management): Next/Previous Desktop do not work #926
2728

2829
### ✈️ Improvements
2930

src-tauri/src/extension/built_in/window_management/backend/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::ffi::c_ushort;
88
use std::ffi::c_void;
99
use std::ops::Deref;
1010
use std::ptr::NonNull;
11+
use std::time::Duration;
1112

1213
use objc2::MainThreadMarker;
1314
use objc2_app_kit::NSEvent;
@@ -303,6 +304,10 @@ pub(crate) fn move_frontmost_window_to_workspace(space: usize) -> Result<(), Err
303304

304305
let window_frame = get_frontmost_window_frame()?;
305306
let close_button_frame = get_frontmost_window_close_button_frame()?;
307+
let prev_mouse_position = unsafe {
308+
let event = CGEvent::new(None);
309+
CGEvent::location(event.as_deref())
310+
};
306311

307312
let mouse_cursor_point = CGPoint::new(
308313
unsafe { CGRectGetMidX(close_button_frame) },
@@ -356,6 +361,9 @@ pub(crate) fn move_frontmost_window_to_workspace(space: usize) -> Result<(), Err
356361
CGEvent::post(CGEventTapLocation::HIDEventTap, mouse_drag_event.as_deref());
357362
}
358363

364+
// Make a slight delay to make sure the window is grabbed
365+
std::thread::sleep(Duration::from_millis(50));
366+
359367
// cast is safe as space is in range [1, 16]
360368
let hot_key: c_ushort = 118 + space as c_ushort - 1;
361369

@@ -398,9 +406,30 @@ pub(crate) fn move_frontmost_window_to_workspace(space: usize) -> Result<(), Err
398406
);
399407
}
400408

409+
// Make a slight delay to finish the space transition animation
410+
std::thread::sleep(Duration::from_millis(50));
411+
412+
/*
413+
* Cleanup
414+
*/
401415
unsafe {
402416
// Let go of the window.
403417
CGEvent::post(CGEventTapLocation::HIDEventTap, mouse_up_event.as_deref());
418+
419+
// Reset mouse position
420+
let mouse_reset_event = {
421+
CGEvent::new_mouse_event(
422+
None,
423+
CGEventType::MouseMoved,
424+
prev_mouse_position,
425+
CGMouseButton::Left,
426+
)
427+
};
428+
CGEvent::set_flags(mouse_reset_event.as_deref(), CGEventFlags(0));
429+
CGEvent::post(
430+
CGEventTapLocation::HIDEventTap,
431+
mouse_reset_event.as_deref(),
432+
);
404433
}
405434

406435
Ok(())

0 commit comments

Comments
 (0)