From 0e8ed8aa4046868d3e2cd32eb564c65f0b8a76c7 Mon Sep 17 00:00:00 2001 From: alex-ds13 <145657253+alex-ds13@users.noreply.github.com> Date: Wed, 2 Apr 2025 19:44:22 +0100 Subject: [PATCH] feat(wm): apply wallpapers per monitor --- komorebi/src/monitor.rs | 3 ++- komorebi/src/window_manager.rs | 7 +++++++ komorebi/src/windows_api.rs | 20 ++++++++++++++++++-- komorebi/src/workspace.rs | 10 +++++----- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/komorebi/src/monitor.rs b/komorebi/src/monitor.rs index 26f447ec..5664d335 100644 --- a/komorebi/src/monitor.rs +++ b/komorebi/src/monitor.rs @@ -177,9 +177,10 @@ impl Monitor { pub fn load_focused_workspace(&mut self, mouse_follows_focus: bool) -> Result<()> { let focused_idx = self.focused_workspace_idx(); + let hmonitor = self.id(); for (i, workspace) in self.workspaces_mut().iter_mut().enumerate() { if i == focused_idx { - workspace.restore(mouse_follows_focus)?; + workspace.restore(mouse_follows_focus, hmonitor)?; } else { workspace.hide(None); } diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 4ccf2a1f..d6eae048 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -1014,6 +1014,7 @@ impl WindowManager { let focused_workspace_idx = monitor.focused_workspace_idx(); monitor.update_workspace_globals(focused_workspace_idx, offset); + let hmonitor = monitor.id(); let workspace = monitor .focused_workspace_mut() .ok_or_else(|| anyhow!("there is no workspace"))?; @@ -1025,6 +1026,12 @@ impl WindowManager { } } + if workspace.wallpaper().is_some() { + if let Err(error) = workspace.apply_wallpaper(hmonitor) { + tracing::error!("failed to apply wallpaper: {}", error); + } + } + workspace.update()?; } diff --git a/komorebi/src/windows_api.rs b/komorebi/src/windows_api.rs index 7281ff0d..b76b8ad0 100644 --- a/komorebi/src/windows_api.rs +++ b/komorebi/src/windows_api.rs @@ -1008,6 +1008,16 @@ impl WindowsApi { Ok(ex_info) } + pub fn monitor_device_path(hmonitor: isize) -> Option { + for display in win32_display_data::connected_displays_all().flatten() { + if display.hmonitor == hmonitor { + return Some(display.device_path.clone()); + } + } + + None + } + pub fn monitor(hmonitor: isize) -> Result { for mut display in win32_display_data::connected_displays_all().flatten() { if display.hmonitor == hmonitor { @@ -1352,7 +1362,7 @@ impl WindowsApi { unsafe { WTSRegisterSessionNotification(HWND(as_ptr!(hwnd)), 1) }.process() } - pub fn set_wallpaper(path: &Path) -> Result<()> { + pub fn set_wallpaper(path: &Path, hmonitor: isize) -> Result<()> { let path = path.canonicalize()?; let wallpaper: IDesktopWallpaper = @@ -1363,9 +1373,15 @@ impl WindowsApi { wallpaper.SetPosition(DWPOS_FILL)?; } + let monitor_id = if let Some(path) = Self::monitor_device_path(hmonitor) { + PCWSTR::from_raw(HSTRING::from(path).as_ptr()) + } else { + PCWSTR::null() + }; + // Set the wallpaper unsafe { - wallpaper.SetWallpaper(PCWSTR::null(), PCWSTR::from_raw(wallpaper_path.as_ptr()))?; + wallpaper.SetWallpaper(monitor_id, PCWSTR::from_raw(wallpaper_path.as_ptr()))?; } Ok(()) } diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index 540a1ec7..4aaaa41e 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -302,9 +302,9 @@ impl Workspace { } } - pub fn apply_wallpaper(&self) -> Result<()> { + pub fn apply_wallpaper(&self, hmonitor: isize) -> Result<()> { if let Some(wallpaper) = &self.wallpaper { - if let Err(error) = WindowsApi::set_wallpaper(&wallpaper.path) { + if let Err(error) = WindowsApi::set_wallpaper(&wallpaper.path, hmonitor) { tracing::error!("failed to set wallpaper: {error}"); } @@ -419,12 +419,12 @@ impl Workspace { Ok(()) } - pub fn restore(&mut self, mouse_follows_focus: bool) -> Result<()> { + pub fn restore(&mut self, mouse_follows_focus: bool, hmonitor: isize) -> Result<()> { if let Some(container) = self.monocle_container() { if let Some(window) = container.focused_window() { container.restore(); window.focus(mouse_follows_focus)?; - return self.apply_wallpaper(); + return self.apply_wallpaper(hmonitor); } } @@ -468,7 +468,7 @@ impl Workspace { floating_window.focus(mouse_follows_focus)?; } - self.apply_wallpaper() + self.apply_wallpaper(hmonitor) } pub fn update(&mut self) -> Result<()> {