aboutsummaryrefslogtreecommitdiff
path: root/src/handlers
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-03-19 14:41:17 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-03-19 18:29:13 +0400
commit3963f537a4182dbcd8e1e2f262ee105473facc56 (patch)
tree942f802863d1f8f63bbe68b53ab2d091e3c7dda9 /src/handlers
parentf31e105043a9fae0fae3dcfe0feb7ea1193d5f77 (diff)
downloadniri-3963f537a4182dbcd8e1e2f262ee105473facc56.tar.gz
niri-3963f537a4182dbcd8e1e2f262ee105473facc56.tar.bz2
niri-3963f537a4182dbcd8e1e2f262ee105473facc56.zip
Wrap mapped windows in a Mapped
Diffstat (limited to 'src/handlers')
-rw-r--r--src/handlers/compositor.rs35
-rw-r--r--src/handlers/mod.rs21
-rw-r--r--src/handlers/xdg_shell.rs25
3 files changed, 42 insertions, 39 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs
index 52c5a193..188ba831 100644
--- a/src/handlers/compositor.rs
+++ b/src/handlers/compositor.rs
@@ -17,8 +17,7 @@ use smithay::wayland::shm::{ShmHandler, ShmState};
use smithay::{delegate_compositor, delegate_shm};
use crate::niri::{ClientState, State};
-use crate::utils::clone2;
-use crate::window::{InitialConfigureState, Unmapped};
+use crate::window::{InitialConfigureState, Mapped, ResolvedWindowRules, Unmapped};
impl CompositorHandler for State {
fn compositor_state(&mut self) -> &mut CompositorState {
@@ -109,22 +108,22 @@ impl CompositorHandler for State {
window.on_commit();
- let (width, is_full_width, output) =
+ let (rules, width, is_full_width, output) =
if let InitialConfigureState::Configured {
+ rules,
width,
is_full_width,
output,
- ..
} = state
{
// Check that the output is still connected.
let output =
output.filter(|o| self.niri.layout.monitor_for_output(o).is_some());
- (width, is_full_width, output)
+ (rules, width, is_full_width, output)
} else {
error!("window map must happen after initial configure");
- (None, false, None)
+ (ResolvedWindowRules::default(), None, false, None)
};
let parent = window
@@ -141,29 +140,30 @@ impl CompositorHandler for State {
.filter(|(_, parent_output)| {
output.is_none() || output.as_ref() == Some(*parent_output)
})
- .map(|(window, _)| window.clone());
+ .map(|(mapped, _)| mapped.window.clone());
- let window = window.clone();
- let win = window.clone();
+ let mapped = Mapped::new(window, rules);
+ let window = mapped.window.clone();
let output = if let Some(p) = parent {
// Open dialogs immediately to the right of their parent window.
self.niri
.layout
- .add_window_right_of(&p, win, width, is_full_width)
+ .add_window_right_of(&p, mapped, width, is_full_width)
} else if let Some(output) = &output {
self.niri
.layout
- .add_window_on_output(output, win, width, is_full_width);
+ .add_window_on_output(output, mapped, width, is_full_width);
Some(output)
} else {
- self.niri.layout.add_window(win, width, is_full_width)
+ self.niri.layout.add_window(mapped, width, is_full_width)
};
if let Some(output) = output.cloned() {
self.niri.layout.start_open_animation_for_window(&window);
- let new_active_window = self.niri.layout.active_window().map(|(w, _)| w);
+ let new_active_window =
+ self.niri.layout.active_window().map(|(m, _)| &m.window);
if new_active_window == Some(&window) {
self.maybe_warp_cursor_to_focus();
}
@@ -183,8 +183,9 @@ impl CompositorHandler for State {
}
// This is a commit of a previously-mapped root or a non-toplevel root.
- if let Some(win_out) = self.niri.layout.find_window_and_output(surface) {
- let (window, output) = clone2(win_out);
+ if let Some((mapped, output)) = self.niri.layout.find_window_and_output(surface) {
+ let window = mapped.window.clone();
+ let output = output.clone();
window.on_commit();
@@ -224,7 +225,9 @@ impl CompositorHandler for State {
// This is a commit of a non-root or a non-toplevel root.
let root_window_output = self.niri.layout.find_window_and_output(&root_surface);
- if let Some((window, output)) = root_window_output.map(clone2) {
+ if let Some((mapped, output)) = root_window_output {
+ let window = mapped.window.clone();
+ let output = output.clone();
window.on_commit();
self.niri.layout.update_window(&window);
self.niri.queue_redraw(output);
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index 4d3a606f..46ee79b6 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -144,7 +144,7 @@ impl InputMethodHandler for State {
self.niri
.layout
.find_window_and_output(parent)
- .map(|(window, _)| window.geometry())
+ .map(|(mapped, _)| mapped.window.geometry())
.unwrap_or_default()
}
}
@@ -333,25 +333,24 @@ impl ForeignToplevelHandler for State {
}
fn activate(&mut self, wl_surface: WlSurface) {
- if let Some((window, _)) = self.niri.layout.find_window_and_output(&wl_surface) {
- let window = window.clone();
+ if let Some((mapped, _)) = self.niri.layout.find_window_and_output(&wl_surface) {
+ let window = mapped.window.clone();
self.niri.layout.activate_window(&window);
self.niri.queue_redraw_all();
}
}
fn close(&mut self, wl_surface: WlSurface) {
- if let Some((window, _)) = self.niri.layout.find_window_and_output(&wl_surface) {
- window.toplevel().expect("no x11 support").send_close();
+ if let Some((mapped, _)) = self.niri.layout.find_window_and_output(&wl_surface) {
+ mapped.toplevel().send_close();
}
}
fn set_fullscreen(&mut self, wl_surface: WlSurface, wl_output: Option<WlOutput>) {
- if let Some((window, current_output)) = self.niri.layout.find_window_and_output(&wl_surface)
+ if let Some((mapped, current_output)) = self.niri.layout.find_window_and_output(&wl_surface)
{
- if !window
+ if !mapped
.toplevel()
- .expect("no x11 support")
.current_state()
.capabilities
.contains(xdg_toplevel::WmCapabilities::Fullscreen)
@@ -359,7 +358,7 @@ impl ForeignToplevelHandler for State {
return;
}
- let window = window.clone();
+ let window = mapped.window.clone();
if let Some(requested_output) = wl_output.as_ref().and_then(Output::from_resource) {
if &requested_output != current_output {
@@ -374,8 +373,8 @@ impl ForeignToplevelHandler for State {
}
fn unset_fullscreen(&mut self, wl_surface: WlSurface) {
- if let Some((window, _)) = self.niri.layout.find_window_and_output(&wl_surface) {
- let window = window.clone();
+ if let Some((mapped, _)) = self.niri.layout.find_window_and_output(&wl_surface) {
+ let window = mapped.window.clone();
self.niri.layout.set_fullscreen(&window, false);
}
}
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs
index 66c3dea4..4d31645c 100644
--- a/src/handlers/xdg_shell.rs
+++ b/src/handlers/xdg_shell.rs
@@ -29,7 +29,6 @@ use smithay::{
use crate::layout::workspace::ColumnWidth;
use crate::niri::{PopupGrabState, State};
-use crate::utils::clone2;
use crate::window::{InitialConfigureState, ResolvedWindowRules, Unmapped};
fn window_matches(role: &XdgToplevelSurfaceRoleAttributes, m: &Match) -> bool {
@@ -213,9 +212,7 @@ impl XdgShellHandler for State {
}
let layout_focus = self.niri.layout.focus();
- if Some(&root)
- != layout_focus.map(|win| win.toplevel().expect("no x11 support").wl_surface())
- {
+ if Some(&root) != layout_focus.map(|win| win.toplevel().wl_surface()) {
let _ = PopupManager::dismiss_popup(&root, &popup);
return;
}
@@ -278,12 +275,12 @@ impl XdgShellHandler for State {
) {
let requested_output = wl_output.as_ref().and_then(Output::from_resource);
- if let Some((window, current_output)) = self
+ if let Some((mapped, current_output)) = self
.niri
.layout
.find_window_and_output(toplevel.wl_surface())
{
- let window = window.clone();
+ let window = mapped.window.clone();
if let Some(requested_output) = requested_output {
if &requested_output != current_output {
@@ -358,12 +355,12 @@ impl XdgShellHandler for State {
}
fn unfullscreen_request(&mut self, toplevel: ToplevelSurface) {
- if let Some((window, _)) = self
+ if let Some((mapped, _)) = self
.niri
.layout
.find_window_and_output(toplevel.wl_surface())
{
- let window = window.clone();
+ let window = mapped.window.clone();
self.niri.layout.set_fullscreen(&window, false);
// A configure is required in response to this event regardless if there are pending
@@ -453,14 +450,16 @@ impl XdgShellHandler for State {
.layout
.find_window_and_output(surface.wl_surface());
- let Some((window, output)) = win_out.map(clone2) else {
+ let Some((mapped, output)) = win_out else {
// I have no idea how this can happen, but I saw it happen once, in a weird interaction
// involving laptop going to sleep and resuming.
error!("toplevel missing from both unmapped_windows and layout");
return;
};
+ let window = mapped.window.clone();
+ let output = output.clone();
- let active_window = self.niri.layout.active_window().map(|(w, _)| w);
+ let active_window = self.niri.layout.active_window().map(|(m, _)| &m.window);
let was_active = active_window == Some(&window);
self.niri.layout.remove_window(&window);
@@ -733,8 +732,8 @@ impl State {
};
// Figure out if the root is a window or a layer surface.
- if let Some((window, output)) = self.niri.layout.find_window_and_output(&root) {
- self.unconstrain_window_popup(popup, window, output);
+ if let Some((mapped, output)) = self.niri.layout.find_window_and_output(&root) {
+ self.unconstrain_window_popup(popup, &mapped.window, output);
} else if let Some((layer_surface, output)) = self.niri.layout.outputs().find_map(|o| {
let map = layer_map_for_output(o);
let layer_surface = map.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL)?;
@@ -814,6 +813,8 @@ impl State {
if let InitialConfigureState::Configured { rules, .. } = &mut unmapped.state {
*rules = resolve();
}
+ } else if let Some(mapped) = self.niri.layout.find_window_mut(toplevel.wl_surface()) {
+ mapped.rules = resolve();
}
}
}