fix: check layer map for root popup surface
This commit is contained in:
parent
a409770df7
commit
e1aa8f7cb4
2 changed files with 68 additions and 40 deletions
|
|
@ -42,7 +42,9 @@ impl WlrLayerShellHandler for State {
|
||||||
fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
|
fn new_popup(&mut self, _parent: WlrLayerSurface, popup: PopupSurface) {
|
||||||
self.common.shell.read().unconstrain_popup(&popup);
|
self.common.shell.read().unconstrain_popup(&popup);
|
||||||
|
|
||||||
if popup.send_configure().is_ok() {
|
if let Err(err) = popup.send_configure() {
|
||||||
|
tracing::warn!("Unable to configure popup. {err:?}",);
|
||||||
|
} else {
|
||||||
self.common
|
self.common
|
||||||
.popups
|
.popups
|
||||||
.track_popup(PopupKind::from(popup))
|
.track_popup(PopupKind::from(popup))
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ use crate::{
|
||||||
shell::{focus::target::KeyboardFocusTarget, grabs::ReleaseMode, CosmicSurface, PendingWindow},
|
shell::{focus::target::KeyboardFocusTarget, grabs::ReleaseMode, CosmicSurface, PendingWindow},
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
};
|
};
|
||||||
|
use smithay::desktop::layer_map_for_output;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
delegate_xdg_shell,
|
delegate_xdg_shell,
|
||||||
desktop::{
|
desktop::{
|
||||||
find_popup_root_surface, PopupGrab, PopupKeyboardGrab, PopupKind, PopupPointerGrab,
|
find_popup_root_surface, PopupGrab, PopupKeyboardGrab, PopupKind, PopupPointerGrab,
|
||||||
PopupUngrabStrategy,
|
PopupUngrabStrategy, WindowSurfaceType,
|
||||||
},
|
},
|
||||||
input::{pointer::Focus, Seat},
|
input::{pointer::Focus, Seat},
|
||||||
output::Output,
|
output::Output,
|
||||||
|
|
@ -63,7 +64,9 @@ impl XdgShellHandler for State {
|
||||||
// let other shells deal with their popups
|
// let other shells deal with their popups
|
||||||
self.common.shell.read().unconstrain_popup(&surface);
|
self.common.shell.read().unconstrain_popup(&surface);
|
||||||
|
|
||||||
if surface.send_configure().is_ok() {
|
if let Err(err) = surface.send_configure() {
|
||||||
|
warn!("Unable to configure popup. {err:?}",);
|
||||||
|
} else {
|
||||||
self.common
|
self.common
|
||||||
.popups
|
.popups
|
||||||
.track_popup(PopupKind::from(surface))
|
.track_popup(PopupKind::from(surface))
|
||||||
|
|
@ -75,52 +78,75 @@ impl XdgShellHandler for State {
|
||||||
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
|
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
|
||||||
let seat = Seat::from_resource(&seat).unwrap();
|
let seat = Seat::from_resource(&seat).unwrap();
|
||||||
let kind = PopupKind::Xdg(surface);
|
let kind = PopupKind::Xdg(surface);
|
||||||
let maybe_root = find_popup_root_surface(&kind)
|
let maybe_root = find_popup_root_surface(&kind).ok();
|
||||||
.ok()
|
if maybe_root.is_none() {
|
||||||
.and_then(|root| self.common.shell.read().element_for_surface(&root).cloned());
|
tracing::warn!("No root surface found for popup grab.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let maybe_root: Option<KeyboardFocusTarget> = maybe_root.and_then(|root| {
|
||||||
|
let shell = self.common.shell.read();
|
||||||
|
shell
|
||||||
|
.element_for_surface(&root)
|
||||||
|
.map(|r| r.clone().into())
|
||||||
|
.or_else(|| {
|
||||||
|
shell.outputs().find_map(|o| {
|
||||||
|
layer_map_for_output(o)
|
||||||
|
.layer_for_surface(&root, WindowSurfaceType::ALL)
|
||||||
|
.cloned()
|
||||||
|
.map(KeyboardFocusTarget::LayerSurface)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
if let Some(root) = maybe_root {
|
if let Some(root) = maybe_root {
|
||||||
let target = root.into();
|
let target = root.into();
|
||||||
let ret = self.common.popups.grab_popup(target, kind, &seat, serial);
|
let ret = self.common.popups.grab_popup(target, kind, &seat, serial);
|
||||||
|
match ret {
|
||||||
if let Ok(mut grab) = ret {
|
Ok(mut grab) => {
|
||||||
if let Some(keyboard) = seat.get_keyboard() {
|
if let Some(keyboard) = seat.get_keyboard() {
|
||||||
if keyboard.is_grabbed()
|
if keyboard.is_grabbed()
|
||||||
&& !(keyboard.has_grab(serial)
|
&& !(keyboard.has_grab(serial)
|
||||||
|| keyboard.has_grab(grab.previous_serial().unwrap_or(serial)))
|
|| keyboard.has_grab(grab.previous_serial().unwrap_or(serial)))
|
||||||
{
|
{
|
||||||
grab.ungrab(PopupUngrabStrategy::All);
|
grab.ungrab(PopupUngrabStrategy::All);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
Shell::set_focus(
|
||||||
|
self,
|
||||||
|
grab.current_grab().as_ref(),
|
||||||
|
&seat,
|
||||||
|
Some(serial),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
keyboard.set_grab(self, PopupKeyboardGrab::new(&grab), serial);
|
||||||
}
|
}
|
||||||
Shell::set_focus(
|
|
||||||
self,
|
|
||||||
grab.current_grab().as_ref(),
|
|
||||||
&seat,
|
|
||||||
Some(serial),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
keyboard.set_grab(self, PopupKeyboardGrab::new(&grab), serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(pointer) = seat.get_pointer() {
|
if let Some(pointer) = seat.get_pointer() {
|
||||||
if pointer.is_grabbed()
|
if pointer.is_grabbed()
|
||||||
&& !(pointer.has_grab(serial)
|
&& !(pointer.has_grab(serial)
|
||||||
|| pointer
|
|| pointer.has_grab(
|
||||||
.has_grab(grab.previous_serial().unwrap_or_else(|| grab.serial())))
|
grab.previous_serial().unwrap_or_else(|| grab.serial()),
|
||||||
{
|
))
|
||||||
grab.ungrab(PopupUngrabStrategy::All);
|
{
|
||||||
return;
|
grab.ungrab(PopupUngrabStrategy::All);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pointer.set_grab(self, PopupPointerGrab::new(&grab), serial, Focus::Keep);
|
||||||
}
|
}
|
||||||
pointer.set_grab(self, PopupPointerGrab::new(&grab), serial, Focus::Keep);
|
|
||||||
}
|
|
||||||
|
|
||||||
seat.user_data()
|
seat.user_data()
|
||||||
.insert_if_missing(|| PopupGrabData::new(None));
|
.insert_if_missing(|| PopupGrabData::new(None));
|
||||||
seat.user_data()
|
seat.user_data()
|
||||||
.get::<PopupGrabData>()
|
.get::<PopupGrabData>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set(Some(grab));
|
.set(Some(grab));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
tracing::warn!("Failed to grab popup: {:?}", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tracing::warn!("No root for grab.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue