From d9a1ec04bd2c58f421377a29841e322ff2e21041 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 31 May 2024 15:35:30 -0700 Subject: [PATCH] Set clipboard/primary focus in `refresh_focus` This should fix https://github.com/pop-os/cosmic-comp/issues/494, and make clipboard and primary focus consistently correct. Changing the active element of a stack needs to change the clipboard focus, but it wasn't being changed since the `KeyboardFocusTarget` was unchanged. The `CosmicStack` methods that change the active stack element also have no obvious way to change the keyboard focus. So we can set this in `refresh_focus`, which should be correct. If the new focus `WlSurface` is `None`, this clears the focus instead of leaving it as the previous code did. I believe that is desirable. Requires https://github.com/Smithay/smithay/pull/1442 to avoid repeated `offer`s, instead of only when focus changed. (Perhaps this could better be solved by having a `WlSurface` variant of `KeyboardFocusTarget`, like pointer focus, or some mechanism for a stack of focus, which could help other things. But it's also unclear exactly how that would work with the code for setting the active stack element, among other questions.) --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/shell/focus/mod.rs | 21 ++++++++++++++++++++- src/wayland/handlers/seat.rs | 17 ++--------------- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3409fbf9..88e0c620 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4581,7 +4581,7 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/smithay//smithay?rev=12bcefc#12bcefc2009c4648bb5e9ffde6e03a4cd4c02d90" +source = "git+https://github.com/smithay//smithay?rev=96af9cb#96af9cb50f686e8c39a6638de3d4ef6b07a239ae" dependencies = [ "appendlist", "ash", diff --git a/Cargo.toml b/Cargo.toml index 2e7dadfe..cd9efd98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,4 +118,4 @@ inherits = "release" lto = "fat" [patch."https://github.com/Smithay/smithay.git"] -smithay = {git = "https://github.com/smithay//smithay", rev = "12bcefc"} +smithay = {git = "https://github.com/smithay//smithay", rev = "96af9cb"} diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index 29574728..5ebf3a74 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -9,9 +9,12 @@ use smithay::{ desktop::{layer_map_for_output, PopupUngrabStrategy}, input::Seat, output::Output, + reexports::wayland_server::Resource, utils::{IsAlive, Serial, SERIAL_COUNTER}, wayland::{ seat::WaylandFocus, + selection::data_device::set_data_device_focus, + selection::primary_selection::set_primary_focus, shell::wlr_layer::{KeyboardInteractivity, Layer}, }, }; @@ -251,7 +254,7 @@ impl Common { .iter() .cloned() .collect::>(); - for seat in seats.into_iter() { + for seat in &seats { let mut shell = state.common.shell.write().unwrap(); let output = seat.active_output(); if !shell.outputs().any(|o| o == &output) { @@ -333,6 +336,22 @@ impl Common { } } + // Update clipboard and primary focus + // + // For now, needs to be here instead of in `focus_changed` to update focus + // when the active element of a stack changes. + for seat in &seats { + if let Some(keyboard) = seat.get_keyboard() { + let focus = keyboard.current_focus(); + let client = focus + .as_ref() + .and_then(|t| t.wl_surface()) + .and_then(|s| state.common.display_handle.get_client(s.id()).ok()); + set_data_device_focus(&state.common.display_handle, &seat, client.clone()); + set_primary_focus(&state.common.display_handle, &seat, client); + } + } + state.common.shell.write().unwrap().update_active() } } diff --git a/src/wayland/handlers/seat.rs b/src/wayland/handlers/seat.rs index a3b1aeb7..c0eded05 100644 --- a/src/wayland/handlers/seat.rs +++ b/src/wayland/handlers/seat.rs @@ -8,11 +8,6 @@ use crate::{ use smithay::{ delegate_seat, input::{keyboard::LedState, pointer::CursorImageStatus, SeatHandler, SeatState}, - reexports::wayland_server::Resource, - wayland::{ - seat::WaylandFocus, selection::data_device::set_data_device_focus, - selection::primary_selection::set_primary_focus, - }, }; use std::cell::RefCell; @@ -39,17 +34,9 @@ impl SeatHandler for State { fn focus_changed( &mut self, - seat: &smithay::input::Seat, - focused: Option<&Self::KeyboardFocus>, + _seat: &smithay::input::Seat, + _focused: Option<&Self::KeyboardFocus>, ) { - let dh = &self.common.display_handle; - if let Some(client) = focused - .and_then(|t| t.wl_surface()) - .and_then(|s| dh.get_client(s.id()).ok()) - { - set_data_device_focus(dh, seat, Some(client.clone())); - set_primary_focus(dh, seat, Some(client)) - } } fn led_state_changed(&mut self, seat: &smithay::input::Seat, led_state: LedState) {