autocommit 2022-04-15 20:23:03 CEST
This commit is contained in:
parent
5f13954dbc
commit
fdf0ab7388
17 changed files with 159 additions and 87 deletions
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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<Logger>,
|
||||
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>) {
|
|||
state.el.stop();
|
||||
}
|
||||
|
||||
fn start_global_event_handlers(state: &Rc<State>, backend: &Rc<dyn Backend>) -> Vec<SpawnedFuture<()>> {
|
||||
fn start_global_event_handlers(
|
||||
state: &Rc<State>,
|
||||
backend: &Rc<dyn Backend>,
|
||||
) -> Vec<SpawnedFuture<()>> {
|
||||
let eng = &state.eng;
|
||||
let mut res = vec![];
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<OwnedFd>,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ pub struct XwindowInfo {
|
|||
pub has_alpha: Cell<bool>,
|
||||
pub override_redirect: Cell<bool>,
|
||||
pub extents: Cell<Rect>,
|
||||
pub pending_extents: Cell<Rect>,
|
||||
pub instance: RefCell<Option<BString>>,
|
||||
pub class: RefCell<Option<BString>>,
|
||||
pub title: RefCell<Option<String>>,
|
||||
|
|
@ -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<Self>, 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() {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<u64, AsyncError>) {
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<State>, 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<State>, 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(())
|
||||
}
|
||||
|
|
|
|||
12
src/xcon.rs
12
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<T: Message<'static>> ReplyHandler for AsyncReplyHandler<T> {
|
|||
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<Self>, t: &T) -> AsyncReply<T::Reply> {
|
||||
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<Self>,
|
||||
t: &T,
|
||||
) -> (AsyncReply<T::Reply>, 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -384,6 +384,7 @@ impl Wm {
|
|||
|
||||
async fn send_configure(&mut self, window: Rc<Xwindow>) {
|
||||
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<XwindowData>>) {
|
||||
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<XwindowData>>) {
|
||||
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<XwindowData>, 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(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue