diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-22 07:52:53 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-22 09:37:26 +0300 |
| commit | c239937fac836f308311eff5f5d5fc5262c6eb55 (patch) | |
| tree | 21c9ea1a03c469e5539a2efbec38145c59f573aa /src | |
| parent | bafa574784297561815d7f6320df6b008d735896 (diff) | |
| download | niri-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.rs | 34 |
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(); |
