hyprshell_windows_lib/overview/
create.rs1use crate::global::{WindowsOverviewConfig, WindowsOverviewData, WindowsOverviewMonitorData};
2use adw::gtk::gdk::{Display, Monitor};
3use adw::gtk::prelude::*;
4use adw::gtk::{Application, ApplicationWindow, FlowBox, Orientation, Overlay, SelectionMode};
5use anyhow::Context;
6use config_lib::{FilterBy, Overview, Windows};
7use core_lib::{HyprlandData, OVERVIEW_NAMESPACE};
8use exec_lib::{get_initial_active, get_monitors};
9use gtk4_layer_shell::{Edge, KeyboardMode, Layer, LayerShell};
10use std::collections::HashMap;
11use tracing::{debug, debug_span};
12
13pub fn create_windows_overview_window(
14 app: &Application,
15 overview: &Overview,
16 windows: &Windows,
17) -> anyhow::Result<WindowsOverviewData> {
18 let _span = debug_span!("create_windows_overview_window").entered();
19 let mut window_list = HashMap::new();
20
21 let monitors = get_monitors();
22 if let Ok(display) = Display::default().context("Could not connect to a display") {
23 let gtk_monitors = display
24 .monitors()
25 .iter()
26 .filter_map(Result::ok)
27 .collect::<Vec<Monitor>>();
28
29 for gtk_monitor in gtk_monitors {
30 let monitor_name = gtk_monitor.connector().unwrap_or_default();
31 if let Some(monitor) = monitors.iter().find(|m| m.name == monitor_name) {
32 let workspaces_flow = FlowBox::builder()
33 .selection_mode(SelectionMode::None)
34 .orientation(Orientation::Horizontal)
35 .max_children_per_line(u32::from(windows.items_per_row))
36 .min_children_per_line(u32::from(windows.items_per_row))
37 .build();
38
39 let workspaces_flow_overlay = Overlay::builder()
40 .child(&workspaces_flow)
41 .css_classes(["monitor"])
42 .build();
43
44 let window = ApplicationWindow::builder()
45 .css_classes(["window"])
46 .application(app)
47 .child(&workspaces_flow_overlay)
48 .default_height(10)
49 .default_width(10)
50 .build();
51
52 window.init_layer_shell();
53 window.set_namespace(Some(OVERVIEW_NAMESPACE));
54 window.set_layer(Layer::Top);
55 window.set_anchor(Edge::Top, true);
56 window.set_margin(Edge::Top, 435i32);
57 window.set_keyboard_mode(KeyboardMode::None);
58 window.set_monitor(Some(>k_monitor));
59 window.present();
60 window.set_visible(false);
61
62 debug!(
63 "Created overview window ({}) for monitor {monitor_name:?}",
64 window.id()
65 );
66 window_list.insert(
67 window,
68 WindowsOverviewMonitorData::new(monitor.id, workspaces_flow),
69 );
70 }
71 }
72 }
73
74 let active = get_initial_active().context("unable to get initial active data")?;
75 Ok(WindowsOverviewData {
76 config: WindowsOverviewConfig {
77 items_per_row: windows.items_per_row,
78 scale: windows.scale,
79 filter_current_workspace: overview.filter_by.contains(&FilterBy::CurrentWorkspace),
80 filter_current_monitor: overview.filter_by.contains(&FilterBy::CurrentMonitor),
81 filter_same_class: overview.filter_by.contains(&FilterBy::SameClass),
82 },
83 window_list,
84 active,
85 initial_active: active,
86 hypr_data: HyprlandData::default(),
87 })
88}