1
0
Fork 0
forked from wry/wry

autocommit 2022-04-15 20:23:03 CEST

This commit is contained in:
Julian Orth 2022-04-15 20:23:03 +02:00
parent 5f13954dbc
commit fdf0ab7388
17 changed files with 159 additions and 87 deletions

View file

@ -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")]

View file

@ -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;

View file

@ -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,
},

View file

@ -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![];

View file

@ -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")
}
}

View file

@ -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>,

View file

@ -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() {

View file

@ -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));

View file

@ -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());
}

View file

@ -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() {

View file

@ -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();

View file

@ -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)
}

View file

@ -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 {

View file

@ -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(())
}

View file

@ -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)
}

View file

@ -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 {

View file

@ -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(())
}