aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-01-23 17:05:08 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-01-23 17:05:08 +0400
commitf5642ab73376582d80da1edbabff8fd5a15632cb (patch)
treeed32658c3a0691da62e970760b8747927ccb9f6f /src
parentab9706cb30c26dafe46c807f0cf073e594c84ef0 (diff)
downloadniri-f5642ab73376582d80da1edbabff8fd5a15632cb.tar.gz
niri-f5642ab73376582d80da1edbabff8fd5a15632cb.tar.bz2
niri-f5642ab73376582d80da1edbabff8fd5a15632cb.zip
Ignore popup grabs when IME keyboard grab is active
Doing this properly will require more refactors, potentially in Smithay. For now let's just ignore popup grabs to make popups work.
Diffstat (limited to 'src')
-rw-r--r--src/handlers/xdg_shell.rs10
-rw-r--r--src/niri.rs33
2 files changed, 33 insertions, 10 deletions
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs
index 221ca222..a8023a69 100644
--- a/src/handlers/xdg_shell.rs
+++ b/src/handlers/xdg_shell.rs
@@ -13,6 +13,7 @@ use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{Logical, Rectangle, Serial};
use smithay::wayland::compositor::{send_surface_state, with_states};
+use smithay::wayland::input_method::InputMethodSeat;
use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState};
use smithay::wayland::shell::wlr_layer::Layer;
use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler;
@@ -94,6 +95,15 @@ impl XdgShellHandler for State {
}
fn grab(&mut self, surface: PopupSurface, _seat: WlSeat, serial: Serial) {
+ // HACK: ignore grabs (pretend they work without actually grabbing) if the input method has
+ // a grab. It will likely need refactors in Smithay to support properly since grabs just
+ // replace each other.
+ // FIXME: do this properly.
+ if self.niri.seat.input_method().keyboard_grabbed() {
+ trace!("ignoring popup grab because IME has keyboard grabbed");
+ return;
+ }
+
let popup = PopupKind::Xdg(surface);
let Ok(root) = find_popup_root_surface(&popup) else {
return;
diff --git a/src/niri.rs b/src/niri.rs
index e275c1ae..4e9bf257 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -66,7 +66,7 @@ use smithay::wayland::compositor::{
};
use smithay::wayland::cursor_shape::CursorShapeManagerState;
use smithay::wayland::dmabuf::DmabufState;
-use smithay::wayland::input_method::InputMethodManagerState;
+use smithay::wayland::input_method::{InputMethodManagerState, InputMethodSeat};
use smithay::wayland::output::OutputManagerState;
use smithay::wayland::pointer_constraints::{with_pointer_constraint, PointerConstraintsState};
use smithay::wayland::pointer_gestures::PointerGesturesState;
@@ -326,7 +326,7 @@ impl State {
self.niri.cursor_manager.check_cursor_image_surface_alive();
self.niri.refresh_pointer_outputs();
self.niri.popups.cleanup();
- self.niri.refresh_popup_grab();
+ self.refresh_popup_grab();
self.update_keyboard_focus();
self.refresh_pointer_focus();
@@ -420,6 +420,27 @@ impl State {
self.move_cursor(center(geo).to_f64());
}
+ pub fn refresh_popup_grab(&mut self) {
+ let keyboard_grabbed = self.niri.seat.input_method().keyboard_grabbed();
+
+ if let Some(grab) = &mut self.niri.popup_grab {
+ if grab.grab.has_ended() {
+ self.niri.popup_grab = None;
+ } else if keyboard_grabbed {
+ // HACK: remove popup grab if IME grabbed the keyboard, because we can't yet do
+ // popup grabs together with an IME grab.
+ // FIXME: do this properly.
+ grab.grab.ungrab(PopupUngrabStrategy::All);
+ self.niri.seat.get_pointer().unwrap().unset_grab(
+ self,
+ SERIAL_COUNTER.next_serial(),
+ get_monotonic_time().as_millis() as u32,
+ );
+ self.niri.popup_grab = None;
+ }
+ }
+ }
+
pub fn update_keyboard_focus(&mut self) {
let focus = if self.niri.is_locked() {
self.niri.lock_surface_focus()
@@ -1560,14 +1581,6 @@ impl Niri {
state.lock_surface.as_ref().map(|s| s.wl_surface()).cloned()
}
- pub fn refresh_popup_grab(&mut self) {
- if let Some(grab) = &self.popup_grab {
- if grab.grab.has_ended() {
- self.popup_grab = None;
- }
- }
- }
-
/// Schedules an immediate redraw on all outputs if one is not already scheduled.
pub fn queue_redraw_all(&mut self) {
let outputs: Vec<_> = self.output_state.keys().cloned().collect();