feat(wm): apply wallpapers per monitor

This commit is contained in:
alex-ds13
2025-04-02 19:44:22 +01:00
committed by Jeezy
parent fa2ccad5bf
commit 0e8ed8aa40
4 changed files with 32 additions and 8 deletions

View File

@@ -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);
}

View File

@@ -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()?;
}

View File

@@ -1008,6 +1008,16 @@ impl WindowsApi {
Ok(ex_info)
}
pub fn monitor_device_path(hmonitor: isize) -> Option<String> {
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<Monitor> {
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(())
}

View File

@@ -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<()> {