Allow toplevels to reconfigure themselves
This commit is contained in:
parent
378421d356
commit
51300780f8
4 changed files with 36 additions and 26 deletions
|
|
@ -125,7 +125,7 @@ impl SurfaceData {
|
|||
output_name
|
||||
}
|
||||
|
||||
fn update_viewport(&self, dims: WindowDims, size_hints: Option<WmNormalHints>) {
|
||||
pub(super) fn update_viewport(&self, dims: WindowDims, size_hints: Option<WmNormalHints>) {
|
||||
let width = (dims.width as f64 / self.scale_factor) as i32;
|
||||
let height = (dims.height as f64 / self.scale_factor) as i32;
|
||||
if width > 0 && height > 0 {
|
||||
|
|
|
|||
|
|
@ -798,8 +798,8 @@ 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 {
|
||||
pub fn can_change_position(&self, window: x::Window) -> bool {
|
||||
let Some(win) = self.windows.get(&window) else {
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
@ -851,6 +851,11 @@ impl<C: XConnection> ServerState<C> {
|
|||
);
|
||||
popup.popup.reposition(&popup.positioner, 0);
|
||||
}
|
||||
Some(SurfaceRole::Toplevel(Some(_))) => {
|
||||
win.attrs.dims.width = dims.width;
|
||||
win.attrs.dims.height = dims.height;
|
||||
data.update_viewport(win.attrs.dims, win.attrs.size_hints);
|
||||
}
|
||||
other => warn!("Non popup ({other:?}) being reconfigured, behavior may be off."),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1574,17 +1574,27 @@ fn reposition_popup() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_toplevel_reconfigure() {
|
||||
fn toplevel_reconfigure() {
|
||||
let (mut f, comp) = TestFixture::new_with_compositor();
|
||||
let toplevel = unsafe { Window::new(1) };
|
||||
let _ = f.create_toplevel(&comp, toplevel);
|
||||
let (_, surface) = f.create_toplevel(&comp, toplevel);
|
||||
|
||||
{
|
||||
let data = f
|
||||
.testwl
|
||||
.get_surface_data(surface)
|
||||
.expect("Missing surface data");
|
||||
let viewport = data.viewport.as_ref().expect("Missing viewport");
|
||||
assert_eq!(viewport.width, 100);
|
||||
assert_eq!(viewport.height, 100);
|
||||
}
|
||||
|
||||
f.satellite.reconfigure_window(x::ConfigureNotifyEvent::new(
|
||||
toplevel,
|
||||
toplevel,
|
||||
x::WINDOW_NONE,
|
||||
40, // x
|
||||
60, // y
|
||||
0, // x
|
||||
0, // y
|
||||
80, // width
|
||||
100, // height
|
||||
0,
|
||||
|
|
@ -1592,16 +1602,13 @@ fn ignore_toplevel_reconfigure() {
|
|||
));
|
||||
|
||||
f.run();
|
||||
let win_data = &f.connection().windows[&toplevel];
|
||||
assert_eq!(
|
||||
win_data.dims,
|
||||
WindowDims {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 100,
|
||||
height: 100
|
||||
}
|
||||
);
|
||||
let data = f
|
||||
.testwl
|
||||
.get_surface_data(surface)
|
||||
.expect("Missing surface data");
|
||||
let viewport = data.viewport.as_ref().expect("Missing viewport");
|
||||
assert_eq!(viewport.width, 80);
|
||||
assert_eq!(viewport.height, 100);
|
||||
}
|
||||
|
||||
type EventMatcher<'a, Event> = Box<dyn FnMut(&Event) -> bool + 'a>;
|
||||
|
|
|
|||
|
|
@ -407,21 +407,19 @@ impl XState {
|
|||
self.handle_property_change(e, server_state);
|
||||
}
|
||||
xcb::Event::X(x::Event::ConfigureRequest(e)) => {
|
||||
if !server_state.can_reconfigure_window(e.window()) {
|
||||
debug!("ignoring reconfigure request for {:?}", e.window());
|
||||
continue;
|
||||
}
|
||||
debug!("{:?} request: {:?}", e.window(), e.value_mask());
|
||||
|
||||
let mut list = Vec::new();
|
||||
let mask = e.value_mask();
|
||||
|
||||
if server_state.can_change_position(e.window()) {
|
||||
if mask.contains(x::ConfigWindowMask::X) {
|
||||
list.push(x::ConfigWindow::X(e.x().into()));
|
||||
}
|
||||
if mask.contains(x::ConfigWindowMask::Y) {
|
||||
list.push(x::ConfigWindow::Y(e.y().into()));
|
||||
}
|
||||
}
|
||||
if mask.contains(x::ConfigWindowMask::WIDTH) {
|
||||
list.push(x::ConfigWindow::Width(e.width().into()));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue