Support repositioning mapped popups
Requires xdg_wm_base version 3+. Helps make some Steam popups act more consistently.
This commit is contained in:
parent
ece5d1bd10
commit
98a81c2668
4 changed files with 169 additions and 34 deletions
|
|
@ -486,7 +486,12 @@ impl<C: XConnection> ServerState<C> {
|
|||
let xdg_wm_base = clientside
|
||||
.global_list
|
||||
.bind::<XdgWmBase, _, _>(&qh, 2..=6, ())
|
||||
.expect("Could not bind XdgWmBase");
|
||||
.expect("Could not bind xdg_wm_base");
|
||||
|
||||
if xdg_wm_base.version() < 3 {
|
||||
warn!("xdg_wm_base version 2 detected. Popup repositioning will not work, and some popups may not work correctly.");
|
||||
}
|
||||
|
||||
let manager = DataDeviceManagerState::bind(&clientside.global_list, &qh)
|
||||
.inspect_err(|e| {
|
||||
warn!("Could not bind data device manager ({e:?}). Clipboard will not work.")
|
||||
|
|
@ -541,15 +546,6 @@ impl<C: XConnection> ServerState<C> {
|
|||
handle_globals::<C>(&self.dh, globals.iter());
|
||||
}
|
||||
|
||||
fn get_object_from_client_object<T, P: Proxy>(&self, proxy: &P) -> Option<&T>
|
||||
where
|
||||
for<'a> &'a T: TryFrom<&'a Object, Error = String>,
|
||||
Globals: wayland_client::Dispatch<P, ObjectKey>,
|
||||
{
|
||||
let key: ObjectKey = proxy.data().copied().unwrap();
|
||||
Some(self.objects.get(key)?.as_ref())
|
||||
}
|
||||
|
||||
pub fn new_window(
|
||||
&mut self,
|
||||
window: x::Window,
|
||||
|
|
@ -645,14 +641,61 @@ impl<C: XConnection> ServerState<C> {
|
|||
win.surface_serial = Some(serial);
|
||||
}
|
||||
|
||||
pub fn can_reconfigure_window(&mut self, window: x::Window) -> bool {
|
||||
let Some(win) = self.windows.get_mut(&window) else {
|
||||
return true;
|
||||
};
|
||||
|
||||
if win.mapped && !win.attrs.override_redirect {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) {
|
||||
let win = self.windows.get_mut(&event.window()).unwrap();
|
||||
win.attrs.dims = WindowDims {
|
||||
let dims = WindowDims {
|
||||
x: event.x(),
|
||||
y: event.y(),
|
||||
width: event.width(),
|
||||
height: event.height(),
|
||||
};
|
||||
if dims == win.attrs.dims {
|
||||
return;
|
||||
}
|
||||
debug!("Reconfiguring {win:?} {:?}", dims);
|
||||
if !win.mapped {
|
||||
win.attrs.dims = dims;
|
||||
return;
|
||||
}
|
||||
|
||||
if self.xdg_wm_base.version() < 3 {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(key) = win.surface_key else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(data): Option<&mut SurfaceData> = self.objects.get_mut(key).map(|o| o.as_mut())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
match &data.role {
|
||||
Some(SurfaceRole::Popup(Some(popup))) => {
|
||||
popup.positioner.set_offset(
|
||||
event.x() as i32 - win.output_offset.x,
|
||||
event.y() as i32 - win.output_offset.y,
|
||||
);
|
||||
popup
|
||||
.positioner
|
||||
.set_size(event.width().into(), event.height().into());
|
||||
popup.popup.reposition(&popup.positioner, 0);
|
||||
}
|
||||
other => warn!("Non popup ({other:?}) being reconfigured, behavior may be off."),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_window(&mut self, window: x::Window) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue