aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-11-22 07:52:53 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-11-22 09:37:26 +0300
commitc239937fac836f308311eff5f5d5fc5262c6eb55 (patch)
tree21c9ea1a03c469e5539a2efbec38145c59f573aa /src
parentbafa574784297561815d7f6320df6b008d735896 (diff)
downloadniri-c239937fac836f308311eff5f5d5fc5262c6eb55.tar.gz
niri-c239937fac836f308311eff5f5d5fc5262c6eb55.tar.bz2
niri-c239937fac836f308311eff5f5d5fc5262c6eb55.zip
Focus target window/output on DnD
In sway, focus-follows-mouse keeps working during DnD, but not in niri. So it can be surprising when you DnD something into another app, but it doesn't get automatically focused. This commit fixes that. Even if the DnD is not validated, or if there's no target surface (e.g. dropped on the niri background), focus the target output, since that's how Firefox's drag-tab-into-new-window works for example.
Diffstat (limited to 'src')
-rw-r--r--src/handlers/mod.rs34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index fcd1fb7d..f7340231 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -306,7 +306,39 @@ impl ClientDndGrabHandler for State {
self.niri.queue_redraw_all();
}
- fn dropped(&mut self, _seat: Seat<Self>) {
+ fn dropped(&mut self, target: Option<WlSurface>, validated: bool, _seat: Seat<Self>) {
+ trace!("client dropped, target: {target:?}, validated: {validated}");
+
+ // Activate the target output, since that's how Firefox drag-tab-into-new-window works for
+ // example. On successful drop, additionally activate the target window.
+ let mut activate_output = true;
+ if let Some(target) = validated.then_some(target).flatten() {
+ if let Some(root) = self.niri.root_surface.get(&target) {
+ if let Some((mapped, _)) = self.niri.layout.find_window_and_output(root) {
+ let window = mapped.window.clone();
+ self.niri.layout.activate_window(&window);
+ activate_output = false;
+ }
+ }
+ }
+
+ if activate_output {
+ // Find the output from cursor coordinates.
+ //
+ // FIXME: uhhh, we can't actually properly tell if the DnD comes from pointer or touch,
+ // and if it comes from touch, then what the coordinates are. Need to pass more
+ // parameters from Smithay I guess.
+ //
+ // Assume that hidden pointer means touch DnD.
+ if !self.niri.pointer_hidden {
+ // We can't even get the current pointer location because it's locked (we're deep
+ // in the grab call stack here). So use the last known one.
+ if let Some(output) = &self.niri.pointer_contents.output {
+ self.niri.layout.activate_output(output);
+ }
+ }
+ }
+
self.niri.dnd_icon = None;
// FIXME: more granular
self.niri.queue_redraw_all();