From fdf0ab73887e4bfbb01e5b49626ac827661c7ac3 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Fri, 15 Apr 2022 20:23:03 +0200 Subject: [PATCH] autocommit 2022-04-15 20:23:03 CEST --- src/acceptor.rs | 17 +++---- src/backends/dummy.rs | 3 +- src/backends/x.rs | 2 +- src/compositor.rs | 21 +++++--- src/dbus.rs | 5 +- src/forker.rs | 2 +- src/ifs/wl_buffer.rs | 11 ++-- src/ifs/wl_seat/event_handling.rs | 1 + src/ifs/wl_seat/kb_owner.rs | 2 + src/ifs/wl_surface/xwindow.rs | 13 +++-- src/main.rs | 2 +- src/tasks/idle.rs | 10 +++- src/tools/tool_client.rs | 4 +- src/user_session.rs | 84 ++++++++++++++++++++----------- src/xcon.rs | 12 ++--- src/xwayland.rs | 4 +- src/xwayland/xwm.rs | 53 ++++++++++++++----- 17 files changed, 159 insertions(+), 87 deletions(-) diff --git a/src/acceptor.rs b/src/acceptor.rs index 1c4c4c1b..7cb619a8 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -3,13 +3,12 @@ use { client::ClientError, event_loop::{EventLoopDispatcher, EventLoopError, EventLoopId}, state::State, - utils::errorfmt::ErrorFmt, + utils::{errorfmt::ErrorFmt, oserror::OsError, xrd::xrd}, }, std::rc::Rc, thiserror::Error, uapi::{c, format_ustr, Errno, OwnedFd, Ustring}, }; -use crate::utils::xrd::xrd; #[derive(Debug, Error)] pub enum AcceptorError { @@ -18,23 +17,23 @@ pub enum AcceptorError { #[error("XDG_RUNTIME_DIR ({0:?}) is too long to form a unix socket address")] XrdTooLong(String), #[error("Could not create a wayland socket")] - SocketFailed(#[source] crate::utils::oserror::OsError), + SocketFailed(#[source] OsError), #[error("Could not stat the existing socket")] - SocketStat(#[source] crate::utils::oserror::OsError), + SocketStat(#[source] OsError), #[error("Could not start listening for incoming connections")] - ListenFailed(#[source] crate::utils::oserror::OsError), + ListenFailed(#[source] OsError), #[error("Could not open the lock file")] - OpenLockFile(#[source] crate::utils::oserror::OsError), + OpenLockFile(#[source] OsError), #[error("Could not lock the lock file")] - LockLockFile(#[source] crate::utils::oserror::OsError), + LockLockFile(#[source] OsError), #[error("The wayland socket is in an error state")] ErrorEvent, #[error("Could not accept new connections")] - AcceptFailed(#[source] crate::utils::oserror::OsError), + AcceptFailed(#[source] OsError), #[error("Could not spawn an event handler for a new connection")] SpawnFailed(#[source] ClientError), #[error("Could not bind the socket to an address")] - BindFailed(#[source] crate::utils::oserror::OsError), + BindFailed(#[source] OsError), #[error("All wayland addresses in the range 0..1000 are already in use")] AddressesInUse, #[error("The event loop caused an error")] diff --git a/src/backends/dummy.rs b/src/backends/dummy.rs index 5aca1634..954df02f 100644 --- a/src/backends/dummy.rs +++ b/src/backends/dummy.rs @@ -1,11 +1,10 @@ -use std::error::Error; use { crate::{ async_engine::SpawnedFuture, backend::{Backend, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId}, video::drm::ConnectorType, }, - std::rc::Rc, + std::{error::Error, rc::Rc}, }; pub struct DummyBackend; diff --git a/src/backends/x.rs b/src/backends/x.rs index c6aaeb5f..ae1a6ca2 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -1,4 +1,3 @@ -use std::error::Error; use { crate::{ async_engine::{Phase, SpawnedFuture}, @@ -52,6 +51,7 @@ use { borrow::Cow, cell::{Cell, RefCell}, collections::VecDeque, + error::Error, future::pending, rc::Rc, }, diff --git a/src/compositor.rs b/src/compositor.rs index bc3e732f..b71cdcd9 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -3,7 +3,10 @@ use { acceptor::{Acceptor, AcceptorError}, async_engine::{AsyncEngine, AsyncError, Phase, SpawnedFuture}, backend::{self, Backend}, - backends::{dummy::DummyOutput, metal, x}, + backends::{ + dummy::{DummyBackend, DummyOutput}, + metal, x, + }, cli::{CliBackend, GlobalArgs, RunArgs}, client::Clients, clientmem::{self, ClientMemError}, @@ -17,12 +20,13 @@ use { logger::Logger, render::{self, RenderError}, sighand::{self, SighandError}, - state::{ConnectorData, IdleState, State}, - tasks, + state::{ConnectorData, IdleState, State, XWaylandState}, + tasks::{self, idle}, tree::{ container_layout, container_render_data, float_layout, float_titles, DisplayNode, NodeIds, OutputNode, WorkspaceNode, }, + user_session::import_environment, utils::{ clonecell::CloneCell, errorfmt::ErrorFmt, fdcloser::FdCloser, oserror::OsError, queue::AsyncQueue, run_toplevel::RunToplevel, tri::Try, @@ -36,10 +40,6 @@ use { thiserror::Error, uapi::c, }; -use crate::backends::dummy::DummyBackend; -use crate::state::XWaylandState; -use crate::tasks::idle; -use crate::user_session::import_environment; pub const MAX_EXTENTS: i32 = (1 << 22) - 1; @@ -85,6 +85,7 @@ fn start_compositor2( logger: Arc, run_args: RunArgs, ) -> Result<(), MainError> { + log::info!("pid = {}", uapi::getpid()); init_fd_limit(); leaks::init(); render::init()?; @@ -154,6 +155,7 @@ fn start_compositor2( forker.setenv(b"_JAVA_AWT_WM_NONREPARENTING", b"1"); let _compositor = engine.spawn(start_compositor3(state.clone())); el.run()?; + state.xwayland.handler.borrow_mut().take(); state.clients.clear(); for (_, seat) in state.globals.seats.lock().deref() { seat.clear(); @@ -190,7 +192,10 @@ async fn start_compositor3(state: Rc) { state.el.stop(); } -fn start_global_event_handlers(state: &Rc, backend: &Rc) -> Vec> { +fn start_global_event_handlers( + state: &Rc, + backend: &Rc, +) -> Vec> { let eng = &state.eng; let mut res = vec![]; diff --git a/src/dbus.rs b/src/dbus.rs index 8f2fbc56..4201bddf 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -13,6 +13,7 @@ use { numcell::NumCell, run_toplevel::RunToplevel, vecstorage::VecStorage, + xrd::{xrd, XRD}, }, }, ahash::AHashMap, @@ -30,7 +31,6 @@ use { thiserror::Error, uapi::OwnedFd, }; -use crate::utils::xrd::{xrd, XRD}; mod auth; mod dynamic_type; @@ -163,8 +163,7 @@ impl Dbus { None => return Err(DbusError::SessionBusAddressNotSet), Some(sba) => sba, }; - self.session - .get(&self.eng, sba, "Session bus") + self.session.get(&self.eng, sba, "Session bus") } } diff --git a/src/forker.rs b/src/forker.rs index 31a54b87..e4ea5a0d 100644 --- a/src/forker.rs +++ b/src/forker.rs @@ -4,6 +4,7 @@ mod io; use { crate::{ async_engine::{AsyncEngine, AsyncFd, SpawnedFuture}, + compositor::{DISPLAY, WAYLAND_DISPLAY}, event_loop::EventLoop, forker::{ clone3::{fork_with_pidfd, Forked}, @@ -35,7 +36,6 @@ use { thiserror::Error, uapi::{c, pipe2, Errno, Fd, IntoUstr, OwnedFd, UstrPtr}, }; -use crate::compositor::{DISPLAY, WAYLAND_DISPLAY}; pub struct ForkerProxy { pidfd: Rc, diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index 6cc79930..fb726b6d 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -102,11 +102,12 @@ impl WlBuffer { match &self.storage { WlBufferStorage::Shm { mem, stride } => { self.texture.set(None); - let ctx = self.client.state.render_ctx.get().unwrap(); - let tex = mem.access(|mem| { - ctx.shmem_texture(mem, self.format, self.width, self.height, *stride) - })??; - self.texture.set(Some(tex)); + if let Some(ctx) = self.client.state.render_ctx.get() { + let tex = mem.access(|mem| { + ctx.shmem_texture(mem, self.format, self.width, self.height, *stride) + })??; + self.texture.set(Some(tex)); + } } WlBufferStorage::Dmabuf(img) => { if self.texture.get().is_none() { diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index 386ed6b1..7c873b2b 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -92,6 +92,7 @@ impl NodeSeatState { while let Some((_, seat)) = self.kb_foci.pop() { seat.ungrab_kb(); seat.keyboard_node.set(seat.state.root.clone()); + log::info!("keyboard_node = root"); if focus_last { if let Some(tl) = seat.toplevel_focus_history.last() { seat.focus_node(tl.focus_surface(seat.id)); diff --git a/src/ifs/wl_seat/kb_owner.rs b/src/ifs/wl_seat/kb_owner.rs index b000c3dd..b820d7d6 100644 --- a/src/ifs/wl_seat/kb_owner.rs +++ b/src/ifs/wl_seat/kb_owner.rs @@ -57,6 +57,7 @@ impl KbOwner for DefaultKbOwner { if old.node_id() == node.node_id() { return; } + log::info!("unfocus {}", old.node_id()); old.node_unfocus(seat); if old.node_seat_state().unfocus(seat) { old.node_active_changed(false); @@ -65,6 +66,7 @@ impl KbOwner for DefaultKbOwner { if node.node_seat_state().focus(seat) { node.node_active_changed(true); } + log::info!("focus {}", node.node_id()); node.clone().node_focus(seat); seat.keyboard_node.set(node.clone()); } diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index f7853a76..a2510fda 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -92,6 +92,7 @@ pub struct XwindowInfo { pub has_alpha: Cell, pub override_redirect: Cell, pub extents: Cell, + pub pending_extents: Cell, pub instance: RefCell>, pub class: RefCell>, pub title: RefCell>, @@ -153,6 +154,7 @@ impl XwindowData { event.height as _, ) .unwrap(); + // log::info!("xwin {} new {:?} or {}", event.window, extents, event.override_redirect); Self { state: state.clone(), window_id: event.window, @@ -161,7 +163,7 @@ impl XwindowData { window: Default::default(), info: XwindowInfo { override_redirect: Cell::new(event.override_redirect != 0), - extents: Cell::new(extents), + pending_extents: Cell::new(extents), ..Default::default() }, children: Default::default(), @@ -275,15 +277,19 @@ impl Xwindow { let map_change = self.map_change(); match map_change { Change::None => return, - Change::Unmap => self.node_destroy(true), + Change::Unmap => { + self.data.info.pending_extents.set(self.data.info.extents.take()); + self.node_destroy(true); + }, Change::Map if self.data.info.override_redirect.get() => { + self.change_extents(&self.data.info.pending_extents.get()); *self.display_link.borrow_mut() = Some(self.data.state.root.stacked.add_last(self.clone())); self.data.state.tree_changed(); } Change::Map if self.data.info.wants_floating.get() => { let ws = self.data.state.float_map_ws(); - let ext = self.data.info.extents.get(); + let ext = self.data.info.pending_extents.get(); self.data .state .map_floating(self.clone(), ext.width(), ext.height(), &ws); @@ -414,6 +420,7 @@ impl SizedNode for Xwindow { } fn change_extents(self: &Rc, rect: &Rect) { + // log::info!("xwin {} change_extents {:?}", self.data.window_id, rect); let old = self.data.info.extents.replace(*rect); if old != *rect { if !self.data.info.override_redirect.get() { diff --git a/src/main.rs b/src/main.rs index 07c4f5c1..002967de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,6 +69,7 @@ mod time; mod tools; mod tree; mod udev; +mod user_session; mod utils; mod video; mod wheel; @@ -78,7 +79,6 @@ mod wire_xcon; mod xcon; mod xkbcommon; mod xwayland; -mod user_session; fn main() { cli::main(); diff --git a/src/tasks/idle.rs b/src/tasks/idle.rs index 97c6eabc..1b10602a 100644 --- a/src/tasks/idle.rs +++ b/src/tasks/idle.rs @@ -51,6 +51,7 @@ impl Idle { _ = self.state.idle.change.triggered().fuse() => self.handle_idle_changes(), } } + log::error!("Due to the above error, monitors will no longer be (de)activated.") } fn handle_expired(&mut self, res: Result) { @@ -78,6 +79,7 @@ impl Idle { if self.idle { self.backend.set_idle(false); self.idle = false; + self.program_timer(self.state.idle.timeout.get()); } } } @@ -98,7 +100,11 @@ fn now() -> c::timespec { fn duration_since(start: c::timespec) -> Duration { let now = now(); - let nanos = - (now.tv_sec as i64 - start.tv_sec as i64) * 1_000_000_000 + (now.tv_nsec - start.tv_nsec); + let mut nanos = + (now.tv_sec as i64 - start.tv_sec as i64) * 1_000_000_000 + (now.tv_nsec as i64 - start.tv_nsec as i64); + if nanos < 0 { + log::error!("Time has gone backwards."); + nanos = 0; + } Duration::from_nanos(nanos as u64) } diff --git a/src/tools/tool_client.rs b/src/tools/tool_client.rs index 0c20991b..ccf30ab0 100644 --- a/src/tools/tool_client.rs +++ b/src/tools/tool_client.rs @@ -2,6 +2,7 @@ use { crate::{ async_engine::{AsyncEngine, AsyncError, SpawnedFuture}, client::{EventFormatter, RequestParser}, + compositor::WAYLAND_DISPLAY, event_loop::{EventLoop, EventLoopError}, logger::Logger, object::{ObjectId, WL_DISPLAY_ID}, @@ -18,6 +19,7 @@ use { oserror::OsError, stack::Stack, vec_ext::VecExt, + xrd::xrd, }, wheel::{Wheel, WheelError}, wire::{ @@ -38,8 +40,6 @@ use { thiserror::Error, uapi::{c, format_ustr}, }; -use crate::compositor::WAYLAND_DISPLAY; -use crate::utils::xrd::xrd; #[derive(Debug, Error)] pub enum ToolClientError { diff --git a/src/user_session.rs b/src/user_session.rs index 6722e578..1f5913f9 100644 --- a/src/user_session.rs +++ b/src/user_session.rs @@ -1,10 +1,13 @@ -use std::borrow::Cow; -use std::rc::Rc; -use thiserror::Error; -use crate::dbus::{BUS_DEST, BUS_PATH, DbusError, DictEntry}; -use crate::state::State; -use crate::utils::errorfmt::ErrorFmt; -use crate::wire_dbus::org; +use { + crate::{ + dbus::{DbusError, DictEntry, BUS_DEST, BUS_PATH}, + state::State, + utils::errorfmt::ErrorFmt, + wire_dbus::org, + }, + std::{borrow::Cow, rc::Rc}, + thiserror::Error, +}; const SYSTEMD_DEST: &str = "org.freedesktop.systemd1"; const SYSTEMD_PATH: &str = "/org/freedesktop/systemd1"; @@ -17,7 +20,12 @@ pub enum UserSessionError { pub fn import_environment(state: &Rc, key: &str, value: &str) { if let Err(e) = import_environment_(state, key, value) { - log::error!("Could not import `{}={}` into the system environment: {}", key, value, ErrorFmt(e)); + log::error!( + "Could not import `{}={}` into the system environment: {}", + key, + value, + ErrorFmt(e) + ); } } @@ -27,28 +35,46 @@ fn import_environment_(state: &Rc, key: &str, value: &str) -> Result<(), Err(e) => return Err(UserSessionError::AcquireSessionBus(e)), }; let setting = format!("{}={}", key, value); - session.call(BUS_DEST, BUS_PATH, org::freedesktop::dbus::UpdateActivationEnvironment { - environment: Cow::Borrowed(&[DictEntry { - key: key.into(), - value: value.into(), - }]) - }, { - let setting = setting.clone(); - move |rep| { - if let Err(e) = rep { - log::error!("Could not import `{}` into the dbus environment: {}", setting, ErrorFmt(e)); + session.call( + BUS_DEST, + BUS_PATH, + org::freedesktop::dbus::UpdateActivationEnvironment { + environment: Cow::Borrowed(&[DictEntry { + key: key.into(), + value: value.into(), + }]), + }, + { + let setting = setting.clone(); + move |rep| { + if let Err(e) = rep { + log::error!( + "Could not import `{}` into the dbus environment: {}", + setting, + ErrorFmt(e) + ); + } } - } - }); - session.call(SYSTEMD_DEST, SYSTEMD_PATH, org::freedesktop::systemd1::manager::SetEnvironment { - names: Cow::Borrowed(&[Cow::Borrowed(&setting)]), - }, { - let setting = setting.clone(); - move |rep| { - if let Err(e) = rep { - log::error!("Could not import `{}` into the systemd environment: {}", setting, ErrorFmt(e)); + }, + ); + session.call( + SYSTEMD_DEST, + SYSTEMD_PATH, + org::freedesktop::systemd1::manager::SetEnvironment { + names: Cow::Borrowed(&[Cow::Borrowed(&setting)]), + }, + { + let setting = setting.clone(); + move |rep| { + if let Err(e) = rep { + log::error!( + "Could not import `{}` into the systemd environment: {}", + setting, + ErrorFmt(e) + ); + } } - } - }); + }, + ); Ok(()) } diff --git a/src/xcon.rs b/src/xcon.rs index a95d367a..c43e65b7 100644 --- a/src/xcon.rs +++ b/src/xcon.rs @@ -6,6 +6,7 @@ pub use crate::xcon::{ use { crate::{ async_engine::{AsyncEngine, AsyncError, Phase, SpawnedFuture}, + compositor::DISPLAY, utils::{ bufio::{BufIo, BufIoError, BufIoMessage}, clonecell::CloneCell, @@ -47,7 +48,6 @@ use { thiserror::Error, uapi::{c, OwnedFd}, }; -use crate::compositor::DISPLAY; pub mod consts; mod formatter; @@ -229,7 +229,7 @@ impl Event { let mut parser = Parser::new(&self.buf, vec![]); let res = M::deserialize(&mut parser); if let Ok(res) = &res { - log::info!("event {:?}", res); + log::trace!("event {:?}", res); } res } @@ -313,7 +313,7 @@ unsafe impl> ReplyHandler for AsyncReplyHandler { return Err(XconError::XconError(e)); } }; - log::info!("result {:?}", msg); + log::trace!("result {:?}", msg); let reply = Reply { bufio: bufio.clone(), buf, @@ -517,7 +517,7 @@ impl Xcon { } pub fn call<'a, T: Request<'a>>(self: &Rc, t: &T) -> AsyncReply { - log::info!("send {:?}", t); + log::trace!("send {:?}", t); self.data.call_with_serial(t, &self.extensions).0 } @@ -525,7 +525,7 @@ impl Xcon { self: &Rc, t: &T, ) -> (AsyncReply, u64) { - log::info!("send {:?}", t); + log::trace!("send {:?}", t); self.data.call_with_serial(t, &self.extensions) } @@ -536,7 +536,7 @@ impl Xcon { event_mask: u32, t: &T, ) -> AsyncReply<()> { - log::info!("send {:?}", t); + log::trace!("send {:?}", t); self.data .send_event(t, &self.extensions, propagate, destination, event_mask) } diff --git a/src/xwayland.rs b/src/xwayland.rs index 3355899b..f4669ea3 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -5,12 +5,14 @@ use { crate::{ async_engine::AsyncError, client::ClientError, + compositor::DISPLAY, forker::{ForkerError, ForkerProxy}, ifs::wl_surface::{ xwindow::{Xwindow, XwindowData}, WlSurface, }, state::State, + user_session::import_environment, utils::{errorfmt::ErrorFmt, oserror::OsError, queue::AsyncQueue, tri::Try}, wire::WlSurfaceId, xcon::XconError, @@ -21,8 +23,6 @@ use { thiserror::Error, uapi::{c, pipe2, Errno, OwnedFd}, }; -use crate::compositor::DISPLAY; -use crate::user_session::import_environment; #[derive(Debug, Error)] enum XWaylandError { diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index b0d7ce1c..0716f9c1 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -384,6 +384,7 @@ impl Wm { async fn send_configure(&mut self, window: Rc) { let extents = window.data.info.extents.get(); + // log::info!("xwin {} send_configure {:?}", window.data.window_id, extents); let cw = ConfigureWindow { window: window.data.window_id, values: ConfigureWindowValues { @@ -438,7 +439,9 @@ impl Wm { } async fn focus_window(&mut self, window: Option<&Rc>) { + log::info!("xwm focus_window {:?}", window.map(|w| w.window_id)); if let Some(old) = mem::replace(&mut self.focus_window, window.cloned()) { + log::info!("xwm unfocus {:?}", old.window_id); self.set_net_wm_state(&old).await; } let window = match window { @@ -459,8 +462,15 @@ impl Wm { } }; if window.info.override_redirect.get() { + log::info!("xwm or => return"); return; } + if let Some(window) = window.window.get() { + let seats = self.state.globals.seats.lock(); + for seat in seats.values() { + seat.focus_toplevel(window.clone()); + } + } let accepts_input = window.info.icccm_hints.input.get(); let mask = if accepts_input { EVENT_MASK_SUBSTRUCTURE_REDIRECT @@ -989,10 +999,13 @@ impl Wm { async fn handle_focus_in(&mut self, revent: &Event) -> Result<(), XWaylandError> { let event: FocusIn = revent.parse()?; + log::info!("xwm focus_in {}", event.event); if matches!(event.mode, NOTIFY_MODE_GRAB | NOTIFY_MODE_UNGRAB) { + log::info!("xwm GRAB/UNGRAB"); return Ok(()); } if matches!(event.detail, NOTIFY_DETAIL_POINTER) { + log::info!("xwm POINTER"); return Ok(()); } let new_window = self.windows.get(&event.event); @@ -1005,6 +1018,7 @@ impl Wm { && prev_pid == new_pid && revent.serial() >= self.last_input_serial { + log::info!("xwm ACCEPT"); focus_window = new_window; } } @@ -1026,6 +1040,7 @@ impl Wm { } async fn activate_window(&mut self, window: Option<&Rc>) { + log::info!("xwm activate_window {:?}", window.map(|w| w.window_id)); if self.focus_window.as_ref().map(|w| w.window_id) == window.map(|w| w.window_id) { return; } @@ -1061,10 +1076,10 @@ impl Wm { async fn handle_property_notify(&mut self, event: &Event) -> Result<(), XWaylandError> { let event: PropertyNotify = event.parse()?; - let name = self.c.call(&GetAtomName { atom: event.atom }).await; - if let Ok(name) = name { - log::info!("{}", name.get().name); - } + // let name = self.c.call(&GetAtomName { atom: event.atom }).await; + // if let Ok(name) = name { + // log::info!("{}", name.get().name); + // } let data = match self.windows.get(&event.window) { Some(w) => w, _ => return Ok(()), @@ -1115,6 +1130,7 @@ impl Wm { Some(w) => w, _ => return Ok(()), }; + log::info!("xwm destroy_notify {}", event.window); data.destroyed.set(true); if let Some(sid) = data.surface_id.take() { self.windows_by_surface_id.remove(&sid); @@ -1228,6 +1244,7 @@ impl Wm { fn update_override_redirect(&self, data: &Rc, or: u8) { let or = or != 0; if data.info.override_redirect.replace(or) != or { + // log::info!("xwin {} or {}", data.window_id, or); if let Some(window) = data.window.get() { window.node_destroy(true); window.map_status_changed(); @@ -1342,18 +1359,28 @@ impl Wm { Some(d) => d, _ => return Ok(()), }; + let extents = Rect::new_sized( + event.x as _, + event.y as _, + event.width as _, + event.height as _, + ) + .unwrap(); + // log::info!("xwin {} configure_notify {:?}", data.window_id, extents); self.update_override_redirect(data, event.override_redirect); if data.info.override_redirect.get() { - if let Some(window) = data.window.get() { - let extents = Rect::new_sized( - event.x as _, - event.y as _, - event.width as _, - event.height as _, - ) + let extents = Rect::new_sized( + event.x as _, + event.y as _, + event.width as _, + event.height as _, + ) .unwrap(); + if let Some(window) = data.window.get() { window.change_extents(&extents); self.state.tree_changed(); + } else { + data.info.pending_extents.set(extents); } } Ok(()) @@ -1370,7 +1397,7 @@ impl Wm { return Ok(()); } } - let de = data.info.extents.get(); + let de = data.info.pending_extents.get(); let mut x1 = de.x1(); let mut y1 = de.y1(); let mut width = de.width(); @@ -1388,7 +1415,7 @@ impl Wm { height = event.height as _; } data.info - .extents + .pending_extents .set(Rect::new_sized(x1, y1, width, height).unwrap()); Ok(()) }