aboutsummaryrefslogtreecommitdiff
path: root/src/handlers
diff options
context:
space:
mode:
authorChristian Meissl <meissl.christian@gmail.com>2024-11-16 22:35:34 +0100
committerIvan Molodetskikh <yalterz@gmail.com>2024-11-29 21:57:36 -0800
commit305fc3b5576c4c6e3d899b3413dbbb8727922cfe (patch)
tree718972dcc035e6d5bb264e519a92d92884bbcf4f /src/handlers
parent61f2ac01d782f1142aefb78d1286db005021a7a0 (diff)
downloadniri-305fc3b5576c4c6e3d899b3413dbbb8727922cfe.tar.gz
niri-305fc3b5576c4c6e3d899b3413dbbb8727922cfe.tar.bz2
niri-305fc3b5576c4c6e3d899b3413dbbb8727922cfe.zip
Activate newly mapped windows with a valid activation token
most of the time the activation token is passed while the window is still unmapped. in this case store the intend to activate the window for later retrieval on map.
Diffstat (limited to 'src/handlers')
-rw-r--r--src/handlers/compositor.rs35
-rw-r--r--src/handlers/mod.rs6
-rw-r--r--src/handlers/xdg_shell.rs2
3 files changed, 35 insertions, 8 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs
index ceb22b78..ed36100b 100644
--- a/src/handlers/compositor.rs
+++ b/src/handlers/compositor.rs
@@ -18,6 +18,8 @@ use smithay::wayland::shm::{ShmHandler, ShmState};
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;
use crate::niri::{ClientState, State};
use crate::utils::send_scale_transform;
use crate::utils::transaction::Transaction;
@@ -84,7 +86,11 @@ impl CompositorHandler for State {
if is_mapped {
// The toplevel got mapped.
- let Unmapped { window, state } = entry.remove();
+ let Unmapped {
+ window,
+ state,
+ activation_token_data,
+ } = entry.remove();
window.on_commit();
@@ -133,8 +139,20 @@ impl CompositorHandler for State {
let mapped = Mapped::new(window, rules, hook);
let window = mapped.window.clone();
+ // Check the token timestamp again in case the window took a while between
+ // requesting activation and mapping.
+ let activate = match activation_token_data
+ .filter(|token| token.timestamp.elapsed() < XDG_ACTIVATION_TOKEN_TIMEOUT)
+ {
+ Some(_) => ActivateWindow::Yes,
+ None => ActivateWindow::Smart,
+ };
+
let output = if let Some(p) = parent {
// Open dialogs immediately to the right of their parent window.
+ //
+ // FIXME: do we want to use activate here? How do we want things to behave
+ // exactly?
self.niri
.layout
.add_window_right_of(&p, mapped, width, is_full_width)
@@ -144,14 +162,21 @@ impl CompositorHandler for State {
mapped,
width,
is_full_width,
+ activate,
)
} else if let Some(output) = &output {
- self.niri
- .layout
- .add_window_on_output(output, mapped, width, is_full_width);
+ self.niri.layout.add_window_on_output(
+ output,
+ mapped,
+ width,
+ is_full_width,
+ activate,
+ );
Some(output)
} else {
- self.niri.layout.add_window(mapped, width, is_full_width)
+ self.niri
+ .layout
+ .add_window(mapped, width, is_full_width, activate)
};
if let Some(output) = output.cloned() {
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index f7340231..b51fc515 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -670,10 +670,12 @@ impl XdgActivationHandler for State {
self.niri.layout.activate_window(&window);
self.niri.layer_shell_on_demand_focus = None;
self.niri.queue_redraw_all();
-
- self.niri.activation_state.remove_token(&token);
+ } else if let Some(unmapped) = self.niri.unmapped_windows.get_mut(&surface) {
+ unmapped.activation_token_data = Some(token_data);
}
}
+
+ self.niri.activation_state.remove_token(&token);
}
}
delegate_xdg_activation!(State);
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs
index 0ac82d79..834bbf64 100644
--- a/src/handlers/xdg_shell.rs
+++ b/src/handlers/xdg_shell.rs
@@ -752,7 +752,7 @@ impl State {
self.niri.is_at_startup,
);
- let Unmapped { window, state } = unmapped;
+ let Unmapped { window, state, .. } = unmapped;
let InitialConfigureState::NotConfigured { wants_fullscreen } = state else {
error!("window must not be already configured in send_initial_configure()");