Center window on screen
This commit is contained in:
parent
e37563eb7a
commit
39a888c7ba
2 changed files with 55 additions and 31 deletions
|
@ -3,14 +3,15 @@ log_level = "trace"
|
|||
[completions]
|
||||
"e" = "emacs"
|
||||
"f" = "firefox"
|
||||
"t" = "terminal"
|
||||
"t" = "xfce4-terminal"
|
||||
"j" = "jetbrains"
|
||||
|
||||
[sources.primary]
|
||||
matcher = "Flex"
|
||||
matcher = "Prefix"
|
||||
source = "Windows"
|
||||
|
||||
[sources.additional]
|
||||
matcher = "Flex"
|
||||
matcher = "Fuse"
|
||||
source = ["Apps", "Shell", "Test"]
|
||||
|
||||
[theme]
|
||||
|
|
|
@ -22,6 +22,7 @@ use winit::window::{Window, WindowBuilder};
|
|||
use xcb::ffi::xcb_connection_t;
|
||||
use xcb::x::{GrabMode, PropMode};
|
||||
use xcb::XidNew;
|
||||
use xcb_wm::ewmh;
|
||||
|
||||
pub fn build_window() -> Result<(Window, EventLoop<()>)> {
|
||||
trace! {"Initialize `winit` event loop"}
|
||||
|
@ -32,7 +33,6 @@ pub fn build_window() -> Result<(Window, EventLoop<()>)> {
|
|||
.with_decorations(false)
|
||||
.with_transparent(true)
|
||||
.with_title("roftl")
|
||||
.with_visible(true)
|
||||
.with_always_on_top(true)
|
||||
.with_override_redirect(true)
|
||||
.build(&event_loop)?;
|
||||
|
@ -49,11 +49,7 @@ fn postprocess_window(window: &Window) -> Result<()> {
|
|||
trace! {"Post-process window for x11"}
|
||||
|
||||
trace! {"Get low level connection and data"}
|
||||
let screen_id = window
|
||||
.xlib_screen_id()
|
||||
.ok_or(anyhow! {"Could not get X11 screen id for the window"})?;
|
||||
|
||||
let xcb_window: xcb::x::Window = unsafe {
|
||||
let xcb_window = unsafe {
|
||||
xcb::x::Window::new(
|
||||
window
|
||||
.xlib_window()
|
||||
|
@ -61,36 +57,67 @@ fn postprocess_window(window: &Window) -> Result<()> {
|
|||
)
|
||||
};
|
||||
|
||||
let xcb_conn_raw = window
|
||||
.xcb_connection()
|
||||
.ok_or(anyhow! {"Cannot get raw xcb connection"})?;
|
||||
|
||||
let xcb_conn = unsafe {
|
||||
mem::ManuallyDrop::new(xcb::Connection::from_raw_conn(mem::transmute(xcb_conn_raw)))
|
||||
let xcb_con = unsafe {
|
||||
let con_raw = window
|
||||
.xcb_connection()
|
||||
.ok_or(anyhow! {"Cannot get raw xcb connection"})?;
|
||||
let con = xcb::Connection::from_raw_conn(con_raw as *mut xcb_connection_t);
|
||||
// xcb::Connection closes the underlying x connection on drop
|
||||
// since the connection is actually owned by the window we have
|
||||
// to prevent the drop
|
||||
mem::ManuallyDrop::new(con)
|
||||
};
|
||||
|
||||
let ewmh_con = xcb_wm::ewmh::Connection::connect(&xcb_con);
|
||||
let icccm_con = xcb_wm::icccm::Connection::connect(&xcb_con);
|
||||
|
||||
trace! {"Unmap window"}
|
||||
let req = xcb::x::UnmapWindow { window: xcb_window };
|
||||
let cookie = xcb_conn.send_request_checked(&req);
|
||||
xcb_conn.check_request(cookie)?;
|
||||
xcb_con.send_and_check_request(&req)?;
|
||||
|
||||
trace! {"Hide window from taskbar"}
|
||||
let xcb_conn = unsafe { xcb::Connection::from_raw_conn(mem::transmute(xcb_conn_raw)) };
|
||||
let ewmh_conn = xcb_wm::ewmh::Connection::connect(&xcb_conn);
|
||||
|
||||
let window_state = xcb_wm::ewmh::proto::SendWmState::new(
|
||||
&ewmh_conn,
|
||||
&ewmh_con,
|
||||
xcb_window,
|
||||
PropMode::Append,
|
||||
[
|
||||
ewmh_conn.atoms._NET_WM_STATE,
|
||||
ewmh_conn.atoms._NET_WM_STATE_SKIP_TASKBAR,
|
||||
ewmh_con.atoms._NET_WM_STATE,
|
||||
ewmh_con.atoms._NET_WM_STATE_SKIP_TASKBAR,
|
||||
],
|
||||
1,
|
||||
);
|
||||
ewmh_conn.send_request(&window_state);
|
||||
ewmh_con.send_request(&window_state);
|
||||
|
||||
let req = xcb::x::MapWindow { window: xcb_window };
|
||||
xcb_conn.send_request(&req);
|
||||
trace! {"Center window on screen"}
|
||||
let screen_pixel = window
|
||||
.current_monitor()
|
||||
.ok_or(anyhow! {"Cannot get screen size"})?
|
||||
.size();
|
||||
|
||||
// usually 0,0 except in multi-head settings (or large display (see icccm spec) which we actually don't consider)
|
||||
let screen_position = window
|
||||
.current_monitor()
|
||||
.ok_or(anyhow! {"Cannot get screen position"})?
|
||||
.position();
|
||||
|
||||
// Configure the window to the center with a size of 800x600 pixels.
|
||||
let window_width = 800u32;
|
||||
let window_height = 300u32;
|
||||
let x = screen_position.x as i32 + (screen_pixel.width as i32 / 2 - window_width as i32 / 2);
|
||||
let y = screen_position.y as i32 + (screen_pixel.height as i32 / 2 - window_height as i32 / 2);
|
||||
|
||||
xcb_con.send_and_check_request(&xcb::x::ConfigureWindow {
|
||||
window: xcb_window,
|
||||
value_list: &[
|
||||
xcb::x::ConfigWindow::X(x),
|
||||
xcb::x::ConfigWindow::Y(y),
|
||||
xcb::x::ConfigWindow::Width(window_width),
|
||||
xcb::x::ConfigWindow::Height(window_height),
|
||||
],
|
||||
})?;
|
||||
|
||||
trace! {"Map window"}
|
||||
xcb_con.send_and_check_request(&xcb::x::MapWindow { window: xcb_window })?;
|
||||
|
||||
trace! {"Grab keyboard"}
|
||||
let req = xcb::x::GrabKeyboard {
|
||||
|
@ -100,11 +127,7 @@ fn postprocess_window(window: &Window) -> Result<()> {
|
|||
pointer_mode: GrabMode::Async,
|
||||
keyboard_mode: GrabMode::Async,
|
||||
};
|
||||
xcb_conn.send_request(&req);
|
||||
|
||||
mem::forget(xcb_conn);
|
||||
|
||||
// trace! {"Center window on screen"}
|
||||
xcb_con.send_request(&req);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue