diff --git a/src/backends/metal.rs b/src/backends/metal.rs index 55995de2..8df14dbe 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -3,7 +3,10 @@ mod monitor; mod video; use crate::async_engine::{AsyncError, AsyncFd}; -use crate::backend::{Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState}; +use crate::backend::{ + Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, + InputEvent, KeyState, +}; use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice}; use crate::dbus::DbusError; use crate::drm::drm::DrmError; @@ -24,6 +27,7 @@ use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; use crate::utils::errorfmt::ErrorFmt; use crate::utils::oserror::OsError; +use crate::utils::smallmap::SmallMap; use crate::utils::syncqueue::SyncQueue; use std::cell::{Cell, RefCell}; use std::ffi::{CStr, CString}; @@ -32,7 +36,6 @@ use std::mem; use std::rc::Rc; use thiserror::Error; use uapi::{c, OwnedFd}; -use crate::utils::smallmap::SmallMap; #[derive(Debug, Error)] pub enum MetalError { diff --git a/src/cli/set_log_level.rs b/src/cli/set_log_level.rs index 672008ba..cb9714bd 100644 --- a/src/cli/set_log_level.rs +++ b/src/cli/set_log_level.rs @@ -1,7 +1,7 @@ -use std::rc::Rc; use crate::cli::{GlobalArgs, SetLogArgs}; use crate::tools::tool_client::ToolClient; use crate::wire::jay_compositor::SetLogLevel; +use std::rc::Rc; pub fn main(global: GlobalArgs, args: SetLogArgs) { let tc = ToolClient::new(global.log_level.into()); diff --git a/src/config/handler.rs b/src/config/handler.rs index 361ec426..00767373 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -18,9 +18,7 @@ use jay_config::input::capability::{ Capability, CAP_GESTURE, CAP_KEYBOARD, CAP_POINTER, CAP_SWITCH, CAP_TABLET_PAD, CAP_TABLET_TOOL, CAP_TOUCH, }; -use jay_config::input::{ - InputDevice, -}; +use jay_config::input::InputDevice; use jay_config::keyboard::keymap::Keymap; use jay_config::keyboard::mods::Modifiers; use jay_config::keyboard::syms::KeySym; diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 4ed23efb..d65b7b4a 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -1,3 +1,4 @@ +use crate::cli::CliLogLevel; use crate::client::{Client, ClientError}; use crate::globals::{Global, GlobalName}; use crate::ifs::jay_log_file::JayLogFile; @@ -6,10 +7,9 @@ use crate::object::Object; use crate::utils::buffd::{MsgParser, MsgParserError}; use crate::wire::jay_compositor::*; use crate::wire::JayCompositorId; -use std::rc::Rc; use log::Level; +use std::rc::Rc; use thiserror::Error; -use crate::cli::CliLogLevel; pub struct JayCompositorGlobal { name: GlobalName, diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index 2671cae4..175ae156 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -197,7 +197,7 @@ impl WlSeatGlobal { let is_container = new.is_container(); for tl in self.toplevel_focus_history.rev_iter() { match tl.as_node().get_workspace() { - Some(ws) if ws.id == workspace.id => { }, + Some(ws) if ws.id == workspace.id => {} _ => continue, }; let parent_is_float = match tl.parent() { @@ -412,7 +412,9 @@ impl WlSeatGlobal { // Enter callbacks impl WlSeatGlobal { pub fn enter_toplevel(self: &Rc, n: Rc) { - self.focus_toplevel(n); + if n.accepts_keyboard_focus() { + self.focus_toplevel(n); + } } pub fn enter_popup(self: &Rc, _n: &Rc) { diff --git a/src/ifs/wl_seat/kb_owner.rs b/src/ifs/wl_seat/kb_owner.rs index 8148212d..5b4a9f6b 100644 --- a/src/ifs/wl_seat/kb_owner.rs +++ b/src/ifs/wl_seat/kb_owner.rs @@ -1,7 +1,7 @@ -use std::ops::Deref; use crate::ifs::wl_seat::WlSeatGlobal; use crate::tree::{Node, OutputNode}; use crate::utils::clonecell::CloneCell; +use std::ops::Deref; use std::rc::Rc; pub struct KbOwnerHolder { diff --git a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs index ef06358a..66256731 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs @@ -1,7 +1,7 @@ use crate::client::{Client, ClientError}; use crate::cursor::KnownCursor; use crate::fixed::Fixed; -use crate::ifs::wl_seat::{ NodeSeatState, WlSeatGlobal}; +use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal}; use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceExt}; use crate::ifs::xdg_positioner::{XdgPositioned, XdgPositioner, CA}; use crate::leaks::Tracker; diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 8929684d..36c5f871 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -12,7 +12,7 @@ use crate::rect::Rect; use crate::render::Renderer; use crate::tree::toplevel::{ToplevelData, ToplevelNode}; use crate::tree::walker::NodeVisitor; -use crate::tree::{FindTreeResult}; +use crate::tree::FindTreeResult; use crate::tree::{FoundNode, Node, NodeId, ToplevelNodeId, WorkspaceNode}; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index fec84891..73e5d968 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -1,4 +1,4 @@ -use crate::client::{Client}; +use crate::client::Client; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal}; @@ -20,7 +20,7 @@ use crate::xwayland::XWaylandEvent; use bstr::BString; use jay_config::Direction; use std::cell::{Cell, RefCell}; -use std::ops::Deref; +use std::ops::{Deref, Not}; use std::rc::Rc; use thiserror::Error; @@ -41,7 +41,7 @@ impl Default for XInputModel { #[derive(Default, Debug)] pub struct IcccmHints { pub flags: Cell, - pub input: Cell, + pub input: Cell, pub initial_state: Cell, pub icon_pixmap: Cell, pub icon_window: Cell, @@ -402,11 +402,12 @@ impl Node for Xwindow { } fn change_extents(self: Rc, rect: &Rect) { - let nw = rect.width(); - let nh = rect.height(); - let de = self.data.info.extents.replace(*rect); - if de.width() != nw || de.height() != nh { + let old = self.data.info.extents.replace(*rect); + if old != *rect { self.events.push(XWaylandEvent::Configure(self.clone())); + if old.position() != rect.position() { + self.surface.set_absolute_position(rect.x1(), rect.y1()); + } } } @@ -442,7 +443,8 @@ impl ToplevelNode for Xwindow { } fn accepts_keyboard_focus(&self) -> bool { - self.data.info.icccm_hints.input.get() != 0 + self.data.info.never_focus.get().not() && + self.data.info.icccm_hints.input.get() } fn default_surface(&self) -> Rc { diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index 8f59a57e..a6cf7738 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -1,5 +1,5 @@ use crate::client::{Client, ClientError}; -use crate::ifs::wl_seat::{NodeSeatState}; +use crate::ifs::wl_seat::NodeSeatState; use crate::ifs::wl_surface::{ CommitAction, CommitContext, SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError, }; diff --git a/src/rect.rs b/src/rect.rs index 0d0a7882..a81e5683 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -178,4 +178,8 @@ impl Rect { pub fn height(&self) -> i32 { self.y2 - self.y1 } + + pub fn position(&self) -> (i32, i32) { + (self.x1, self.y1) + } } diff --git a/src/tree/container.rs b/src/tree/container.rs index f0f1c54e..408e06e3 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -1,4 +1,4 @@ -use crate::backend::{KeyState}; +use crate::backend::KeyState; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT}; diff --git a/src/tree/float.rs b/src/tree/float.rs index 3f1ba115..20296c86 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -1,4 +1,4 @@ -use crate::backend::{KeyState}; +use crate::backend::KeyState; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT}; diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index 41da67ad..0e7c7d63 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -1,6 +1,6 @@ use crate::ifs::wl_seat::SeatId; use crate::ifs::wl_surface::WlSurface; -use crate::tree::{Node}; +use crate::tree::Node; use crate::utils::linkedlist::LinkedNode; use crate::utils::numcell::NumCell; use crate::utils::smallmap::SmallMap; diff --git a/src/xcon.rs b/src/xcon.rs index 3033f173..29f0c210 100644 --- a/src/xcon.rs +++ b/src/xcon.rs @@ -214,7 +214,11 @@ impl Event { pub fn parse<'a, M: Message<'a>>(&'a self) -> Result { let mut parser = Parser::new(&self.buf, vec![]); - M::deserialize(&mut parser) + let res = M::deserialize(&mut parser); + if let Ok(res) = &res { + log::info!("event {:?}", res); + } + res } } @@ -296,6 +300,7 @@ unsafe impl> ReplyHandler for AsyncReplyHandler { return Err(XconError::XconError(e)); } }; + log::info!("result {:?}", msg); let reply = Reply { bufio: bufio.clone(), buf, @@ -499,6 +504,7 @@ impl Xcon { } pub fn call<'a, T: Request<'a>>(self: &Rc, t: &T) -> AsyncReply { + log::info!("send {:?}", t); self.data.call_with_serial(t, &self.extensions).0 } @@ -506,6 +512,7 @@ impl Xcon { self: &Rc, t: &T, ) -> (AsyncReply, u64) { + log::info!("send {:?}", t); self.data.call_with_serial(t, &self.extensions) } @@ -516,6 +523,7 @@ impl Xcon { event_mask: u32, t: &T, ) -> AsyncReply<()> { + log::info!("send {:?}", t); self.data .send_event(t, &self.extensions, propagate, destination, event_mask) } diff --git a/src/xcon/consts.rs b/src/xcon/consts.rs index 5a25f379..39fe11ec 100644 --- a/src/xcon/consts.rs +++ b/src/xcon/consts.rs @@ -251,3 +251,17 @@ pub const _NET_WM_MOVERESIZE_MOVE: u32 = 8; pub const _NET_WM_MOVERESIZE_SIZE_KEYBOARD: u32 = 9; pub const _NET_WM_MOVERESIZE_MOVE_KEYBOARD: u32 = 10; pub const _NET_WM_MOVERESIZE_CANCEL: u32 = 11; + +pub const STACK_MODE_ABOVE : u32 = 0; +pub const STACK_MODE_BELOW : u32 = 1; +pub const STACK_MODE_TOP_IF : u32 = 2; +pub const STACK_MODE_BOTTOM_IF : u32 = 3; +pub const STACK_MODE_OPPOSITE : u32 = 4; + +pub const CONFIG_WINDOW_X : u16 = 1; +pub const CONFIG_WINDOW_Y : u16 = 2; +pub const CONFIG_WINDOW_WIDTH : u16 = 4; +pub const CONFIG_WINDOW_HEIGHT : u16 = 8; +pub const CONFIG_WINDOW_BORDER_WIDTH : u16 = 16; +pub const CONFIG_WINDOW_SIBLING : u16 = 32; +pub const CONFIG_WINDOW_STACK_MODE : u16 = 64; diff --git a/src/xcon/wire_type.rs b/src/xcon/wire_type.rs index b9e526b1..d5cd7a7f 100644 --- a/src/xcon/wire_type.rs +++ b/src/xcon/wire_type.rs @@ -3,6 +3,7 @@ use crate::xcon::parser::Parser; use crate::xcon::XconError; use bstr::{BStr, ByteSlice}; use std::borrow::Cow; +use std::fmt::Debug; use std::rc::Rc; use uapi::OwnedFd; @@ -11,7 +12,7 @@ fn unimplemented() -> ! { unimplemented!(); } -pub unsafe trait Message<'a>: Clone + 'a { +pub unsafe trait Message<'a>: Clone + Debug + 'a { type Generic<'b>: Message<'b>; const IS_POD: bool; const HAS_FDS: bool; diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index f26b077b..82c0d1aa 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -9,23 +9,8 @@ use crate::utils::errorfmt::ErrorFmt; use crate::utils::linkedlist::LinkedList; use crate::utils::queue::AsyncQueue; use crate::wire::WlSurfaceId; -use crate::wire_xcon::{ - ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, - ConfigureNotify, ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateNotify, - CreateWindow, CreateWindowValues, DestroyNotify, FocusIn, GetGeometry, InternAtom, KillClient, - MapNotify, MapRequest, MapWindow, PropertyNotify, ResClientIdSpec, ResQueryClientIds, - SetInputFocus, SetSelectionOwner, UnmapNotify, -}; -use crate::xcon::consts::{ - ATOM_ATOM, ATOM_STRING, ATOM_WINDOW, ATOM_WM_CLASS, ATOM_WM_NAME, ATOM_WM_SIZE_HINTS, - ATOM_WM_TRANSIENT_FOR, COMPOSITE_REDIRECT_MANUAL, EVENT_MASK_FOCUS_CHANGE, - EVENT_MASK_PROPERTY_CHANGE, EVENT_MASK_SUBSTRUCTURE_NOTIFY, EVENT_MASK_SUBSTRUCTURE_REDIRECT, - ICCCM_WM_HINT_INPUT, ICCCM_WM_STATE_ICONIC, ICCCM_WM_STATE_NORMAL, ICCCM_WM_STATE_WITHDRAWN, - INPUT_FOCUS_POINTER_ROOT, MWM_HINTS_DECORATIONS_FIELD, MWM_HINTS_FLAGS_FIELD, - NOTIFY_DETAIL_POINTER, NOTIFY_MODE_GRAB, NOTIFY_MODE_UNGRAB, PROP_MODE_REPLACE, - RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID, WINDOW_CLASS_INPUT_OUTPUT, _NET_WM_STATE_ADD, - _NET_WM_STATE_REMOVE, _NET_WM_STATE_TOGGLE, -}; +use crate::wire_xcon::{ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, ConfigureNotify, ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateNotify, CreateWindow, CreateWindowValues, DestroyNotify, FocusIn, GetAtomName, GetGeometry, InternAtom, KillClient, MapNotify, MapRequest, MapWindow, PropertyNotify, ResClientIdSpec, ResQueryClientIds, SetInputFocus, SetSelectionOwner, UnmapNotify}; +use crate::xcon::consts::{ATOM_ATOM, ATOM_STRING, ATOM_WINDOW, ATOM_WM_CLASS, ATOM_WM_NAME, ATOM_WM_SIZE_HINTS, ATOM_WM_TRANSIENT_FOR, COMPOSITE_REDIRECT_MANUAL, EVENT_MASK_FOCUS_CHANGE, EVENT_MASK_PROPERTY_CHANGE, EVENT_MASK_SUBSTRUCTURE_NOTIFY, EVENT_MASK_SUBSTRUCTURE_REDIRECT, ICCCM_WM_HINT_INPUT, ICCCM_WM_STATE_ICONIC, ICCCM_WM_STATE_NORMAL, ICCCM_WM_STATE_WITHDRAWN, INPUT_FOCUS_POINTER_ROOT, MWM_HINTS_DECORATIONS_FIELD, MWM_HINTS_FLAGS_FIELD, NOTIFY_DETAIL_POINTER, NOTIFY_MODE_GRAB, NOTIFY_MODE_UNGRAB, PROP_MODE_REPLACE, RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID, WINDOW_CLASS_INPUT_OUTPUT, _NET_WM_STATE_ADD, _NET_WM_STATE_REMOVE, _NET_WM_STATE_TOGGLE, STACK_MODE_ABOVE, STACK_MODE_BELOW, CONFIG_WINDOW_X, CONFIG_WINDOW_Y, CONFIG_WINDOW_WIDTH, CONFIG_WINDOW_HEIGHT}; use crate::xcon::{Event, XEvent, Xcon, XconError}; use crate::xwayland::{XWaylandError, XWaylandEvent}; use ahash::{AHashMap, AHashSet}; @@ -447,7 +432,8 @@ impl Wm { if window.info.override_redirect.get() { return; } - let accepts_input = window.info.icccm_hints.input.get() != 0; + let accepts_input = window.info.icccm_hints.input.get(); + log::info!("{:?} ai {}", window.info.title, accepts_input); let mask = if accepts_input { EVENT_MASK_SUBSTRUCTURE_REDIRECT } else { @@ -502,7 +488,7 @@ impl Wm { fn compute_input_model(&self, data: &Rc) { let has_wm_take_focus = data.info.protocols.contains(&self.atoms.WM_TAKE_FOCUS); - let accepts_input = data.info.icccm_hints.input.get() != 0; + let accepts_input = data.info.icccm_hints.input.get(); let model = match (accepts_input, has_wm_take_focus) { (false, false) => XInputModel::None, (true, false) => XInputModel::Passive, @@ -664,13 +650,14 @@ impl Wm { if !matches!(e, XconError::PropertyUnavailable) { log::error!("Could not retrieve WM_HINTS property: {}", ErrorFmt(e)); } + data.info.icccm_hints.input.set(true); return; } let mut values = [0; 9]; let len = values.len().min(buf.len()); values[..len].copy_from_slice(&buf[..len]); data.info.icccm_hints.flags.set(values[0] as i32); - data.info.icccm_hints.input.set(values[1]); + data.info.icccm_hints.input.set(values[1] != 0); data.info.icccm_hints.initial_state.set(values[2] as i32); data.info.icccm_hints.icon_pixmap.set(values[3]); data.info.icccm_hints.icon_window.set(values[4]); @@ -685,7 +672,7 @@ impl Wm { .get() .not_contains(ICCCM_WM_HINT_INPUT) { - data.info.icccm_hints.input.set(1); + data.info.icccm_hints.input.set(true); } self.compute_input_model(data); } @@ -1027,6 +1014,12 @@ 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 data = match self.windows.get(&event.window) { Some(w) => w, _ => return Ok(()), @@ -1093,7 +1086,9 @@ impl Wm { child.parent.set(None); } } - self.activate_window(None).await; + if self.focus_window.as_ref().map(|w| w.window_id) == Some(event.window) { + self.activate_window(None).await; + } Ok(()) } @@ -1263,6 +1258,20 @@ impl Wm { } }; *window.stack_link.borrow_mut() = Some(link); + let res = self.c.call(&ConfigureWindow { + window: window.window_id, + values: ConfigureWindowValues { + sibling: sibling.map(|s| s.window_id), + stack_mode: Some(match above { + true => STACK_MODE_ABOVE, + false => STACK_MODE_BELOW, + }), + ..Default::default() + }, + }).await; + if let Err(e) = res { + log::warn!("Could not restack window: {}", ErrorFmt(e)); + } self.set_net_client_list_stacking().await; } @@ -1308,9 +1317,29 @@ impl Wm { Some(d) => d, _ => return Ok(()), }; - if let Some(w) = data.window.get() { - self.send_configure(w).await; + if let Some(window) = data.window.get() { + if window.is_mapped() { + return Ok(()); + } } + let de = data.info.extents.get(); + let mut x1 = de.x1(); + let mut y1 = de.y1(); + let mut width = de.width(); + let mut height = de.height(); + if event.value_mask.contains(CONFIG_WINDOW_X) { + x1 = event.x as _; + } + if event.value_mask.contains(CONFIG_WINDOW_Y) { + y1 = event.y as _; + } + if event.value_mask.contains(CONFIG_WINDOW_WIDTH) { + width = event.width as _; + } + if event.value_mask.contains(CONFIG_WINDOW_HEIGHT) { + height = event.height as _; + } + data.info.extents.set(Rect::new_sized(x1, y1, width, height).unwrap()); Ok(()) }