parent
02bee5aea7
commit
601223d3ae
3 changed files with 46 additions and 43 deletions
|
|
@ -42,6 +42,21 @@ impl From<xcb::ProtocolError> for MaybeBadWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
type XResult<T> = Result<T, MaybeBadWindow>;
|
type XResult<T> = Result<T, MaybeBadWindow>;
|
||||||
|
macro_rules! unwrap_or_skip_bad_window {
|
||||||
|
($err:expr) => {
|
||||||
|
match $err {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
let err = MaybeBadWindow::from(e);
|
||||||
|
match err {
|
||||||
|
MaybeBadWindow::BadWindow => return,
|
||||||
|
MaybeBadWindow::Other(other) => panic!("X11 protocol error: {other:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Essentially a trait alias.
|
/// Essentially a trait alias.
|
||||||
trait PropertyResolver {
|
trait PropertyResolver {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
@ -194,7 +209,7 @@ impl XState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_events(&mut self, server_state: &mut super::RealServerState) {
|
pub fn handle_events(&mut self, server_state: &mut super::RealServerState) {
|
||||||
macro_rules! unwrap_or_skip_bad_window {
|
macro_rules! unwrap_or_skip_bad_window_cont {
|
||||||
($err:expr) => {
|
($err:expr) => {
|
||||||
match $err {
|
match $err {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
|
@ -225,7 +240,7 @@ impl XState {
|
||||||
debug!("reparent event: {e:?}");
|
debug!("reparent event: {e:?}");
|
||||||
if e.parent() == self.root {
|
if e.parent() == self.root {
|
||||||
let attrs =
|
let attrs =
|
||||||
unwrap_or_skip_bad_window!(self.get_window_attributes(e.window()));
|
unwrap_or_skip_bad_window_cont!(self.get_window_attributes(e.window()));
|
||||||
server_state.new_window(
|
server_state.new_window(
|
||||||
e.window(),
|
e.window(),
|
||||||
attrs.override_redirect,
|
attrs.override_redirect,
|
||||||
|
|
@ -240,18 +255,19 @@ impl XState {
|
||||||
}
|
}
|
||||||
xcb::Event::X(x::Event::MapRequest(e)) => {
|
xcb::Event::X(x::Event::MapRequest(e)) => {
|
||||||
debug!("requested to map {:?}", e.window());
|
debug!("requested to map {:?}", e.window());
|
||||||
unwrap_or_skip_bad_window!(self
|
unwrap_or_skip_bad_window_cont!(self
|
||||||
.connection
|
.connection
|
||||||
.send_and_check_request(&x::MapWindow { window: e.window() }));
|
.send_and_check_request(&x::MapWindow { window: e.window() }));
|
||||||
}
|
}
|
||||||
xcb::Event::X(x::Event::MapNotify(e)) => {
|
xcb::Event::X(x::Event::MapNotify(e)) => {
|
||||||
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(
|
unwrap_or_skip_bad_window_cont!(self.connection.send_and_check_request(
|
||||||
&x::ChangeWindowAttributes {
|
&x::ChangeWindowAttributes {
|
||||||
window: e.window(),
|
window: e.window(),
|
||||||
value_list: &[x::Cw::EventMask(x::EventMask::PROPERTY_CHANGE)],
|
value_list: &[x::Cw::EventMask(x::EventMask::PROPERTY_CHANGE)],
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
let attrs = unwrap_or_skip_bad_window!(self.get_window_attributes(e.window()));
|
let attrs =
|
||||||
|
unwrap_or_skip_bad_window_cont!(self.get_window_attributes(e.window()));
|
||||||
self.handle_window_attributes(server_state, e.window(), attrs);
|
self.handle_window_attributes(server_state, e.window(), attrs);
|
||||||
server_state.map_window(e.window());
|
server_state.map_window(e.window());
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +277,7 @@ impl XState {
|
||||||
xcb::Event::X(x::Event::UnmapNotify(e)) => {
|
xcb::Event::X(x::Event::UnmapNotify(e)) => {
|
||||||
trace!("unmap event: {:?}", e.event());
|
trace!("unmap event: {:?}", e.event());
|
||||||
server_state.unmap_window(e.window());
|
server_state.unmap_window(e.window());
|
||||||
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(
|
unwrap_or_skip_bad_window_cont!(self.connection.send_and_check_request(
|
||||||
&x::ChangeWindowAttributes {
|
&x::ChangeWindowAttributes {
|
||||||
window: e.window(),
|
window: e.window(),
|
||||||
value_list: &[x::Cw::EventMask(x::EventMask::empty())],
|
value_list: &[x::Cw::EventMask(x::EventMask::empty())],
|
||||||
|
|
@ -316,7 +332,7 @@ impl XState {
|
||||||
list.push(x::ConfigWindow::Height(e.height().into()));
|
list.push(x::ConfigWindow::Height(e.height().into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(
|
unwrap_or_skip_bad_window_cont!(self.connection.send_and_check_request(
|
||||||
&x::ConfigureWindow {
|
&x::ConfigureWindow {
|
||||||
window: e.window(),
|
window: e.window(),
|
||||||
value_list: &list,
|
value_list: &list,
|
||||||
|
|
@ -553,20 +569,6 @@ impl XState {
|
||||||
}
|
}
|
||||||
|
|
||||||
let window = event.window();
|
let window = event.window();
|
||||||
macro_rules! unwrap_or_skip_bad_window {
|
|
||||||
($err:expr) => {
|
|
||||||
match $err {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(e) => {
|
|
||||||
let err = MaybeBadWindow::from(e);
|
|
||||||
match err {
|
|
||||||
MaybeBadWindow::BadWindow => return,
|
|
||||||
MaybeBadWindow::Other(other) => panic!("X11 protocol error: {other:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
match event.atom() {
|
match event.atom() {
|
||||||
x if x == x::ATOM_WM_HINTS => {
|
x if x == x::ATOM_WM_HINTS => {
|
||||||
|
|
@ -751,7 +753,7 @@ impl super::XConnection for Arc<xcb::Connection> {
|
||||||
|
|
||||||
fn set_window_dims(&mut self, window: x::Window, dims: crate::server::PendingSurfaceState) {
|
fn set_window_dims(&mut self, window: x::Window, dims: crate::server::PendingSurfaceState) {
|
||||||
trace!("reconfiguring window {window:?}");
|
trace!("reconfiguring window {window:?}");
|
||||||
self.send_and_check_request(&x::ConfigureWindow {
|
unwrap_or_skip_bad_window!(self.send_and_check_request(&x::ConfigureWindow {
|
||||||
window,
|
window,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::ConfigWindow::X(dims.x),
|
x::ConfigWindow::X(dims.x),
|
||||||
|
|
@ -759,8 +761,7 @@ impl super::XConnection for Arc<xcb::Connection> {
|
||||||
x::ConfigWindow::Width(dims.width as _),
|
x::ConfigWindow::Width(dims.width as _),
|
||||||
x::ConfigWindow::Height(dims.height as _),
|
x::ConfigWindow::Height(dims.height as _),
|
||||||
],
|
],
|
||||||
})
|
}));
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool, atoms: Self::ExtraData) {
|
fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool, atoms: Self::ExtraData) {
|
||||||
|
|
@ -780,16 +781,15 @@ impl super::XConnection for Arc<xcb::Connection> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_window(&mut self, window: x::Window, atoms: Self::ExtraData) {
|
fn focus_window(&mut self, window: x::Window, atoms: Self::ExtraData) {
|
||||||
let prop = self
|
let prop =
|
||||||
.wait_for_reply(self.send_request(&x::GetProperty {
|
unwrap_or_skip_bad_window!(self.wait_for_reply(self.send_request(&x::GetProperty {
|
||||||
delete: false,
|
delete: false,
|
||||||
window,
|
window,
|
||||||
property: x::ATOM_WM_HINTS,
|
property: x::ATOM_WM_HINTS,
|
||||||
r#type: x::ATOM_WM_HINTS,
|
r#type: x::ATOM_WM_HINTS,
|
||||||
long_offset: 0,
|
long_offset: 0,
|
||||||
long_length: 9,
|
long_length: 9,
|
||||||
}))
|
})));
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let set_focus = if prop.r#type() == x::ATOM_NONE {
|
let set_focus = if prop.r#type() == x::ATOM_NONE {
|
||||||
true
|
true
|
||||||
|
|
@ -806,19 +806,17 @@ impl super::XConnection for Arc<xcb::Connection> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.send_and_check_request(&x::ConfigureWindow {
|
unwrap_or_skip_bad_window!(self.send_and_check_request(&x::ConfigureWindow {
|
||||||
window,
|
window,
|
||||||
value_list: &[x::ConfigWindow::StackMode(x::StackMode::Above)],
|
value_list: &[x::ConfigWindow::StackMode(x::StackMode::Above)],
|
||||||
})
|
}));
|
||||||
.unwrap();
|
unwrap_or_skip_bad_window!(self.send_and_check_request(&x::ChangeProperty {
|
||||||
self.send_and_check_request(&x::ChangeProperty {
|
|
||||||
mode: x::PropMode::Replace,
|
mode: x::PropMode::Replace,
|
||||||
window: self.root_window(),
|
window: self.root_window(),
|
||||||
property: atoms.active_win,
|
property: atoms.active_win,
|
||||||
r#type: x::ATOM_WINDOW,
|
r#type: x::ATOM_WINDOW,
|
||||||
data: &[window],
|
data: &[window],
|
||||||
})
|
}));
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_window(&mut self, window: x::Window, atoms: Self::ExtraData) {
|
fn close_window(&mut self, window: x::Window, atoms: Self::ExtraData) {
|
||||||
|
|
@ -829,13 +827,12 @@ impl super::XConnection for Arc<xcb::Connection> {
|
||||||
x::ClientMessageData::Data32(data),
|
x::ClientMessageData::Data32(data),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.send_and_check_request(&x::SendEvent {
|
unwrap_or_skip_bad_window!(self.send_and_check_request(&x::SendEvent {
|
||||||
destination: x::SendEventDest::Window(window),
|
destination: x::SendEventDest::Window(window),
|
||||||
propagate: false,
|
propagate: false,
|
||||||
event_mask: x::EventMask::empty(),
|
event_mask: x::EventMask::empty(),
|
||||||
event,
|
event,
|
||||||
})
|
}));
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -536,6 +536,11 @@ fn quick_delete() {
|
||||||
|
|
||||||
let window = connection.new_window(connection.root, 0, 0, 20, 20, false);
|
let window = connection.new_window(connection.root, 0, 0, 20, 20, false);
|
||||||
connection.map_window(window);
|
connection.map_window(window);
|
||||||
|
f.wait_and_dispatch();
|
||||||
|
let surf = f
|
||||||
|
.testwl
|
||||||
|
.last_created_surface_id()
|
||||||
|
.expect("No surface created");
|
||||||
connection.set_property(
|
connection.set_property(
|
||||||
window,
|
window,
|
||||||
x::ATOM_WM_HINTS,
|
x::ATOM_WM_HINTS,
|
||||||
|
|
@ -567,12 +572,10 @@ fn quick_delete() {
|
||||||
value_list: &[x::ConfigWindow::X(10), x::ConfigWindow::Y(40)],
|
value_list: &[x::ConfigWindow::X(10), x::ConfigWindow::Y(40)],
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
f.testwl
|
||||||
|
.configure_toplevel(surf, 100, 100, vec![xdg_toplevel::State::Activated]);
|
||||||
connection.destroy_window(window);
|
connection.destroy_window(window);
|
||||||
f.wait_and_dispatch();
|
f.wait_and_dispatch();
|
||||||
|
|
||||||
let last_surf = f
|
assert_eq!(f.testwl.get_surface_data(surf), None);
|
||||||
.testwl
|
|
||||||
.last_created_surface_id()
|
|
||||||
.expect("No surface created");
|
|
||||||
assert_eq!(f.testwl.get_surface_data(last_surf), None);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,10 @@ impl State {
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn get_toplevel(&mut self, surface_id: SurfaceId) -> &mut Toplevel {
|
fn get_toplevel(&mut self, surface_id: SurfaceId) -> &mut Toplevel {
|
||||||
let surface = self.surfaces.get_mut(&surface_id).unwrap();
|
let surface = self
|
||||||
|
.surfaces
|
||||||
|
.get_mut(&surface_id)
|
||||||
|
.expect("Surface does not exist");
|
||||||
match &mut surface.role {
|
match &mut surface.role {
|
||||||
Some(SurfaceRole::Toplevel(t)) => t,
|
Some(SurfaceRole::Toplevel(t)) => t,
|
||||||
other => panic!("Surface does not have toplevel role: {:?}", other),
|
other => panic!("Surface does not have toplevel role: {:?}", other),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue