aboutsummaryrefslogtreecommitdiff
path: root/src/handlers/compositor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/handlers/compositor.rs')
-rw-r--r--src/handlers/compositor.rs91
1 files changed, 64 insertions, 27 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs
index cf2efaaf..a7761824 100644
--- a/src/handlers/compositor.rs
+++ b/src/handlers/compositor.rs
@@ -20,7 +20,7 @@ use smithay::{delegate_compositor, delegate_shm};
use super::xdg_shell::add_mapped_toplevel_pre_commit_hook;
use crate::handlers::XDG_ACTIVATION_TOKEN_TIMEOUT;
-use crate::layout::{ActivateWindow, AddWindowTarget};
+use crate::layout::{ActivateWindow, AddWindowTarget, LayoutElement as _};
use crate::niri::{CastTarget, ClientState, LockState, State};
use crate::utils::transaction::Transaction;
use crate::utils::{is_mapped, send_scale_transform};
@@ -91,35 +91,59 @@ impl CompositorHandler for State {
let toplevel = window.toplevel().expect("no X11 support");
- let (rules, width, height, is_full_width, output, workspace_id) =
- if let InitialConfigureState::Configured {
+ let (
+ rules,
+ width,
+ height,
+ is_full_width,
+ output,
+ workspace_id,
+ is_pending_maximized,
+ ) = if let InitialConfigureState::Configured {
+ rules,
+ width,
+ height,
+ floating_width: _,
+ floating_height: _,
+ is_full_width,
+ output,
+ workspace_name,
+ is_pending_maximized,
+ } = state
+ {
+ // Check that the output is still connected.
+ let output =
+ output.filter(|o| self.niri.layout.monitor_for_output(o).is_some());
+
+ // Check that the workspace still exists.
+ let workspace_id = workspace_name
+ .as_deref()
+ .and_then(|n| self.niri.layout.find_workspace_by_name(n))
+ .map(|(_, ws)| ws.id());
+
+ (
rules,
width,
height,
- floating_width: _,
- floating_height: _,
is_full_width,
output,
- workspace_name,
- } = state
- {
- // Check that the output is still connected.
- let output =
- output.filter(|o| self.niri.layout.monitor_for_output(o).is_some());
-
- // Check that the workspace still exists.
- let workspace_id = workspace_name
- .as_deref()
- .and_then(|n| self.niri.layout.find_workspace_by_name(n))
- .map(|(_, ws)| ws.id());
-
- (rules, width, height, is_full_width, output, workspace_id)
- } else {
- // Can happen when a surface unmaps by attaching a null buffer while
- // there are in-flight pending configures.
- debug!("window mapped without proper initial configure");
- (ResolvedWindowRules::empty(), None, None, false, None, None)
- };
+ workspace_id,
+ is_pending_maximized,
+ )
+ } else {
+ // Can happen when a surface unmaps by attaching a null buffer while
+ // there are in-flight pending configures.
+ debug!("window mapped without proper initial configure");
+ (
+ ResolvedWindowRules::empty(),
+ None,
+ None,
+ false,
+ None,
+ None,
+ false,
+ )
+ };
// The GTK about dialog sets min/max size after the initial configure but
// before mapping, so we need to compute open_floating at the last possible
@@ -169,7 +193,7 @@ impl CompositorHandler for State {
.map(|(mapped, _)| mapped.window.clone());
// The mapped pre-commit hook deals with dma-bufs on its own.
- self.remove_default_dmabuf_pre_commit_hook(toplevel.wl_surface());
+ self.remove_default_dmabuf_pre_commit_hook(surface);
let hook = add_mapped_toplevel_pre_commit_hook(toplevel);
let mapped = Mapped::new(window, rules, hook);
let window = mapped.window.clone();
@@ -193,8 +217,21 @@ impl CompositorHandler for State {
is_floating,
activate,
);
+ let output = output.cloned();
+
+ // The window state cannot contain Fullscreen and Maximized at once. Therefore,
+ // if the window ended up fullscreen, then we only know that it is also
+ // maximized from the is_pending_maximized variable. Tell the layout about it
+ // here so that unfullscreening the window makes it maximized.
+ if let Some((mapped, _)) = self.niri.layout.find_window_and_output(surface) {
+ if mapped.pending_sizing_mode().is_fullscreen() && is_pending_maximized {
+ self.niri.layout.set_maximized(&window, true);
+ }
+ } else {
+ error!("layout is missing the window that we just added");
+ }
- if let Some(output) = output.cloned() {
+ if let Some(output) = output {
self.niri.layout.start_open_animation_for_window(&window);
let new_focus = self.niri.layout.focus().map(|m| &m.window);