mirror of
https://github.com/wez/wezterm.git
synced 2024-09-21 03:39:16 +03:00
window: implement FullScreen for x11
refs: https://github.com/wez/wezterm/issues/177
This commit is contained in:
parent
4d8cc1bb26
commit
c68bf92bcd
@ -19,6 +19,7 @@ use xcb_util::ffi::keysyms::{xcb_key_symbols_alloc, xcb_key_symbols_free, xcb_ke
|
||||
pub struct XConnection {
|
||||
pub conn: xcb_util::ewmh::Connection,
|
||||
pub screen_num: i32,
|
||||
pub root: xcb::xproto::Window,
|
||||
pub keyboard: Keyboard,
|
||||
pub kbd_ev: u8,
|
||||
pub atom_protocols: xcb::Atom,
|
||||
@ -390,10 +391,13 @@ impl XConnection {
|
||||
.request_check()
|
||||
.context("xcb::open_font_checked")?;
|
||||
|
||||
let root = screen.root();
|
||||
|
||||
let conn = XConnection {
|
||||
conn,
|
||||
cursor_font_id,
|
||||
screen_num,
|
||||
root,
|
||||
atom_protocols,
|
||||
atom_clipboard,
|
||||
atom_delete,
|
||||
|
@ -629,8 +629,69 @@ impl XWindowInner {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_fullscreen(&self) -> anyhow::Result<bool> {
|
||||
let conn = self.conn();
|
||||
|
||||
let net_wm_state = xcb::intern_atom(conn.conn(), false, "_NET_WM_STATE")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
let net_wm_state_fullscreen =
|
||||
xcb::intern_atom(conn.conn(), false, "_NET_WM_STATE_FULLSCREEN")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
|
||||
let reply = xcb::xproto::get_property(
|
||||
&conn,
|
||||
false,
|
||||
self.window_id,
|
||||
net_wm_state,
|
||||
xcb::xproto::ATOM_ATOM,
|
||||
0,
|
||||
1024,
|
||||
)
|
||||
.get_reply()?;
|
||||
|
||||
let state = reply.value::<u32>();
|
||||
|
||||
Ok(state
|
||||
.iter()
|
||||
.position(|&x| x == net_wm_state_fullscreen)
|
||||
.is_some())
|
||||
}
|
||||
|
||||
fn set_fullscreen_hint(&mut self, enable: bool) -> anyhow::Result<()> {
|
||||
let conn = self.conn();
|
||||
|
||||
let net_wm_state = xcb::intern_atom(conn.conn(), false, "_NET_WM_STATE")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
let net_wm_state_fullscreen =
|
||||
xcb::intern_atom(conn.conn(), false, "_NET_WM_STATE_FULLSCREEN")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
|
||||
let data: [u32; 5] = [if enable { 1 } else { 0 }, net_wm_state_fullscreen, 0, 0, 0];
|
||||
|
||||
// Ask window manager to change our fullscreen state
|
||||
xcb::xproto::send_event(
|
||||
&conn,
|
||||
true,
|
||||
conn.root,
|
||||
xcb::xproto::EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
||||
| xcb::xproto::EVENT_MASK_SUBSTRUCTURE_NOTIFY,
|
||||
&xcb::xproto::ClientMessageEvent::new(
|
||||
32,
|
||||
self.window_id,
|
||||
net_wm_state,
|
||||
xcb::ClientMessageData::from_data32(data),
|
||||
),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code, clippy::identity_op)]
|
||||
fn disable_decorations(&mut self) -> anyhow::Result<()> {
|
||||
fn adjust_decorations(&mut self, enable: bool) -> anyhow::Result<()> {
|
||||
// Set the motif hints to disable decorations.
|
||||
// See https://stackoverflow.com/a/1909708
|
||||
#[repr(C)]
|
||||
@ -654,7 +715,7 @@ impl XWindowInner {
|
||||
let hints = MwmHints {
|
||||
flags: HINTS_DECORATIONS,
|
||||
functions: 0,
|
||||
decorations: 0, // off
|
||||
decorations: if enable { FUNC_ALL } else { 0 },
|
||||
input_mode: 0,
|
||||
status: 0,
|
||||
};
|
||||
@ -843,6 +904,17 @@ impl WindowOpsMut for XWindowInner {
|
||||
self.paint_all = true;
|
||||
}
|
||||
|
||||
fn toggle_fullscreen(&mut self) {
|
||||
let fullscreen = match self.is_fullscreen() {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
log::error!("Failed to determine fullscreen state: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
self.set_fullscreen_hint(!fullscreen).ok();
|
||||
}
|
||||
|
||||
fn set_inner_size(&mut self, width: usize, height: usize) {
|
||||
xcb::configure_window(
|
||||
self.conn().conn(),
|
||||
@ -872,24 +944,9 @@ impl WindowOpsMut for XWindowInner {
|
||||
| xcb_util::ewmh::MOVE_RESIZE_WINDOW_Y,
|
||||
coords.x as u32,
|
||||
coords.y as u32,
|
||||
// these dimensions are ignored because we're not
|
||||
// passing the relevant MOVE_RESIZE_XX flags above,
|
||||
// but are preserved here for clarity on what these
|
||||
// parameters do
|
||||
self.width as u32,
|
||||
self.height as u32,
|
||||
);
|
||||
|
||||
/*
|
||||
xcb::configure_window(
|
||||
self.conn.conn(),
|
||||
self.window_id,
|
||||
&[
|
||||
(xcb::CONFIG_WINDOW_X as u16, coords.x as u32),
|
||||
(xcb::CONFIG_WINDOW_Y as u16, coords.y as u32),
|
||||
],
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
/// Change the title for the window manager
|
||||
@ -933,6 +990,13 @@ impl WindowOps for XWindow {
|
||||
})
|
||||
}
|
||||
|
||||
fn toggle_fullscreen(&self) -> Future<()> {
|
||||
XConnection::with_window_inner(self.0, |inner| {
|
||||
inner.toggle_fullscreen();
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn show(&self) -> Future<()> {
|
||||
XConnection::with_window_inner(self.0, |inner| {
|
||||
inner.show();
|
||||
|
@ -134,6 +134,14 @@ impl WindowOps for Window {
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_fullscreen(&self) -> Future<()> {
|
||||
match self {
|
||||
Self::X11(x) => x.toggle_fullscreen(),
|
||||
#[cfg(feature = "wayland")]
|
||||
Self::Wayland(w) => w.toggle_fullscreen(),
|
||||
}
|
||||
}
|
||||
|
||||
fn show(&self) -> Future<()> {
|
||||
match self {
|
||||
Self::X11(x) => x.show(),
|
||||
|
Loading…
Reference in New Issue
Block a user