Browse / github.com/storytold/photocraft / patch
Extra windows share the main window's app id, so Wayland docks and window rules see them (#6697)
Extra windows share the main window's app id, so Wayland docks and window rules see them (#6697) Partly addresses #6697 (Hyprland: let PhotoCraft's windows float, tile and move between workspaces). ## Problem The main window sets a Wayland app id (`ai.storyteller.photocraft`), but the extra OS windows are built from `egui::ViewportBuilder::default()` and have none: - document windows (Window › New Window, `canvas::tabs::extra_windows`) - Camera Raw (`dialogs::camera_raw_ui::controls`) - the X11/Windows screen color picker (`dialogs::screen_picker`) On Hyprland (0.56.2, Omarchy), `hyprctl clients` showed them with an **empty class**, so no window rule can target them, and they tile lik
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- TaylorBurke (imported from pull request #9894, open)
- Base
dacecbfea1d5ca3270b44d09ac35e3d195618cb0- Size
- +24 −5 in 6 files
- Review
- pending
- Shared
- 2026-10-28
- Id
b17bbefb9c1cdf705a9172a6
How it went
No other operator has reported using it yet.
Diff
raw · apps/photocraft/src/main.rs crates/ui-egui/src/canvas/tabs.rs crates/ui-egui/src/dialogs/camera_raw_ui/controls.rs crates/ui-egui/src/dialogs/screen_picker.rs crates/ui-egui/src/lib.rs crates/ui-egui/src/os_window.rs
@@ -75,8 +75,7 @@ mod window_frame; use photocraft_engine::Session; use photocraft_ui_egui::PhotocraftApp; -/// Matches the `.desktop` file and hicolor icon name, so Wayland docks pick up the icon.-const APP_ID: &str = "ai.storyteller.photocraft";+use photocraft_ui_egui::os_window::APP_ID; /// Windows and Linux: no OS title bar; the app's top bar is the title bar, with its own caption /// buttons and edge resizing (`photocraft_ui_egui::titlebar`), as Photoshop does on Windows. macOS@@ -704,7 +704,7 @@ pub fn extra_windows(app: &mut PhotocraftApp, ctx: &egui::Context) { let Some(st) = app.session.documents().get(w.document) else { continue }; let title = format!("{} — window {}", st.doc.name, w.id); let vid = egui::ViewportId::from_hash_of(("docwin", w.id));- let mut builder = egui::ViewportBuilder::default().with_title(title).with_inner_size([800.0, 600.0]);+ let mut builder = crate::os_window::builder().with_title(title).with_inner_size([800.0, 600.0]); if let Some([x, y]) = w.position { builder = builder.with_position([x, y]); }@@ -197,7 +197,7 @@ pub fn show(app: &mut PhotocraftApp, ctx: &egui::Context) { ui.painter().rect_filled(r, 0.0, Tokens::get(ui.ctx()).scrim); }); // A window of its own (title bar, moved and resized like any window), like Adobe Camera Raw.- let builder = egui::ViewportBuilder::default().with_title(window_title).with_inner_size([1360.0, 900.0]).with_min_inner_size([900.0, 600.0]);+ let builder = crate::os_window::builder().with_title(window_title).with_inner_size([1360.0, 900.0]).with_min_inner_size([900.0, 600.0]); let mut close = false; ctx.show_viewport_immediate(egui::ViewportId::from_hash_of("camera-raw-window"), builder, |ui, class| { if ui.ctx().input(|i| i.viewport().close_requested()) {@@ -261,7 +261,7 @@ pub fn cancel(ctx: &Context) { /// The picker window: hidden until its snapshot has been painted (#3210). fn viewport_builder(ctx: &Context, image: &ScreenImage) -> egui::ViewportBuilder {- let mut builder = egui::ViewportBuilder::default()+ let mut builder = crate::os_window::builder() .with_title(tl!("PhotoCraft — Screen Color Picker")) .with_decorations(false) .with_resizable(false)@@ -30,6 +30,7 @@ pub mod menu_catalog; pub mod menus; pub mod monitor_status; pub mod notices;+pub mod os_window; pub mod panels; pub mod preset_files_ui; pub mod proxy;new file mode 100644@@ -0,0 +1,19 @@+//! Extra OS windows (document windows, Camera Raw, the screen color picker) share the main+//! window's app id, so docks show the PhotoCraft icon on them and Wayland compositors' window+//! rules can match them (Hyprland's `class:`, #6697). Without one their app id is empty.++/// Matches the `.desktop` file and hicolor icon name, so Wayland docks pick up the icon.+pub const APP_ID: &str = "ai.storyteller.photocraft";++/// A builder for an extra OS window, carrying [`APP_ID`].+pub fn builder() -> egui::ViewportBuilder {+ egui::ViewportBuilder::default().with_app_id(APP_ID)+}++#[cfg(test)]+mod tests {+ #[test]+ fn extra_windows_carry_the_app_id() {+ assert_eq!(super::builder().app_id.as_deref(), Some("ai.storyteller.photocraft"));+ }+}