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]
|
[completions]
|
||||||
"e" = "emacs"
|
"e" = "emacs"
|
||||||
"f" = "firefox"
|
"f" = "firefox"
|
||||||
"t" = "terminal"
|
"t" = "xfce4-terminal"
|
||||||
|
"j" = "jetbrains"
|
||||||
|
|
||||||
[sources.primary]
|
[sources.primary]
|
||||||
matcher = "Flex"
|
matcher = "Prefix"
|
||||||
source = "Windows"
|
source = "Windows"
|
||||||
|
|
||||||
[sources.additional]
|
[sources.additional]
|
||||||
matcher = "Flex"
|
matcher = "Fuse"
|
||||||
source = ["Apps", "Shell", "Test"]
|
source = ["Apps", "Shell", "Test"]
|
||||||
|
|
||||||
[theme]
|
[theme]
|
||||||
|
|
|
@ -22,6 +22,7 @@ use winit::window::{Window, WindowBuilder};
|
||||||
use xcb::ffi::xcb_connection_t;
|
use xcb::ffi::xcb_connection_t;
|
||||||
use xcb::x::{GrabMode, PropMode};
|
use xcb::x::{GrabMode, PropMode};
|
||||||
use xcb::XidNew;
|
use xcb::XidNew;
|
||||||
|
use xcb_wm::ewmh;
|
||||||
|
|
||||||
pub fn build_window() -> Result<(Window, EventLoop<()>)> {
|
pub fn build_window() -> Result<(Window, EventLoop<()>)> {
|
||||||
trace! {"Initialize `winit` event loop"}
|
trace! {"Initialize `winit` event loop"}
|
||||||
|
@ -32,7 +33,6 @@ pub fn build_window() -> Result<(Window, EventLoop<()>)> {
|
||||||
.with_decorations(false)
|
.with_decorations(false)
|
||||||
.with_transparent(true)
|
.with_transparent(true)
|
||||||
.with_title("roftl")
|
.with_title("roftl")
|
||||||
.with_visible(true)
|
|
||||||
.with_always_on_top(true)
|
.with_always_on_top(true)
|
||||||
.with_override_redirect(true)
|
.with_override_redirect(true)
|
||||||
.build(&event_loop)?;
|
.build(&event_loop)?;
|
||||||
|
@ -49,11 +49,7 @@ fn postprocess_window(window: &Window) -> Result<()> {
|
||||||
trace! {"Post-process window for x11"}
|
trace! {"Post-process window for x11"}
|
||||||
|
|
||||||
trace! {"Get low level connection and data"}
|
trace! {"Get low level connection and data"}
|
||||||
let screen_id = window
|
let xcb_window = unsafe {
|
||||||
.xlib_screen_id()
|
|
||||||
.ok_or(anyhow! {"Could not get X11 screen id for the window"})?;
|
|
||||||
|
|
||||||
let xcb_window: xcb::x::Window = unsafe {
|
|
||||||
xcb::x::Window::new(
|
xcb::x::Window::new(
|
||||||
window
|
window
|
||||||
.xlib_window()
|
.xlib_window()
|
||||||
|
@ -61,36 +57,67 @@ fn postprocess_window(window: &Window) -> Result<()> {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let xcb_conn_raw = window
|
let xcb_con = unsafe {
|
||||||
|
let con_raw = window
|
||||||
.xcb_connection()
|
.xcb_connection()
|
||||||
.ok_or(anyhow! {"Cannot get raw xcb connection"})?;
|
.ok_or(anyhow! {"Cannot get raw xcb connection"})?;
|
||||||
|
let con = xcb::Connection::from_raw_conn(con_raw as *mut xcb_connection_t);
|
||||||
let xcb_conn = unsafe {
|
// xcb::Connection closes the underlying x connection on drop
|
||||||
mem::ManuallyDrop::new(xcb::Connection::from_raw_conn(mem::transmute(xcb_conn_raw)))
|
// 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 req = xcb::x::UnmapWindow { window: xcb_window };
|
||||||
let cookie = xcb_conn.send_request_checked(&req);
|
xcb_con.send_and_check_request(&req)?;
|
||||||
xcb_conn.check_request(cookie)?;
|
|
||||||
|
|
||||||
trace! {"Hide window from taskbar"}
|
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(
|
let window_state = xcb_wm::ewmh::proto::SendWmState::new(
|
||||||
&ewmh_conn,
|
&ewmh_con,
|
||||||
xcb_window,
|
xcb_window,
|
||||||
PropMode::Append,
|
PropMode::Append,
|
||||||
[
|
[
|
||||||
ewmh_conn.atoms._NET_WM_STATE,
|
ewmh_con.atoms._NET_WM_STATE,
|
||||||
ewmh_conn.atoms._NET_WM_STATE_SKIP_TASKBAR,
|
ewmh_con.atoms._NET_WM_STATE_SKIP_TASKBAR,
|
||||||
],
|
],
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
ewmh_conn.send_request(&window_state);
|
ewmh_con.send_request(&window_state);
|
||||||
|
|
||||||
let req = xcb::x::MapWindow { window: xcb_window };
|
trace! {"Center window on screen"}
|
||||||
xcb_conn.send_request(&req);
|
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"}
|
trace! {"Grab keyboard"}
|
||||||
let req = xcb::x::GrabKeyboard {
|
let req = xcb::x::GrabKeyboard {
|
||||||
|
@ -100,11 +127,7 @@ fn postprocess_window(window: &Window) -> Result<()> {
|
||||||
pointer_mode: GrabMode::Async,
|
pointer_mode: GrabMode::Async,
|
||||||
keyboard_mode: GrabMode::Async,
|
keyboard_mode: GrabMode::Async,
|
||||||
};
|
};
|
||||||
xcb_conn.send_request(&req);
|
xcb_con.send_request(&req);
|
||||||
|
|
||||||
mem::forget(xcb_conn);
|
|
||||||
|
|
||||||
// trace! {"Center window on screen"}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue