Skip to content

Commit

Permalink
fix(bar.rs): use native windows api to reserve space instead of komorebi
Browse files Browse the repository at this point in the history
resolves #62, further work needed in #63
  • Loading branch information
codyduong committed Jan 24, 2025
1 parent 959025b commit 56a9a48
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 41 deletions.
1 change: 1 addition & 0 deletions docs/gen_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ def default_transformer(item: RootItem, filepath: str) -> str:
create_transformer("Align", default_matcher, "alias", "api/Align")
create_transformer("Component", default_matcher, "alias", "api/Component")
create_transformer("ComponentProps", default_matcher, "alias", "api/ComponentProps")
# create_transformer("BarPosition", default_matcher, "type", "api/BarProps")

create_transformer("MemoryInfo", default_matcher, "type", "api/MemoryInfo")
create_transformer("CpuLoadInfo", default_matcher, "type", "api/CpuLoadInfo")
Expand Down
12 changes: 6 additions & 6 deletions examples/testbench/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ for _, monitor in ipairs(monitors) do
{
Weather = {
format = function(r)
hitokage.debug("fuck yea", r)
return "{{temp_fahrenheit}} °F hell yeah"
return "{{temp_fahrenheit}} °F"
end,
},
},
Expand Down Expand Up @@ -176,10 +175,11 @@ for _, monitor in ipairs(monitors) do
},
homogeneous = true,
width = monitor.geometry.width - 16,
offset = {
x = 8,
y = 8,
},
-- offset = {
-- x = 8,
-- y = 32,
-- },
position = "Bottom"
})
)
::continue::
Expand Down
121 changes: 86 additions & 35 deletions hitokage-core/src/components/bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use std::hash::Hasher;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use windows::Win32::Foundation::{HWND, LPARAM, LRESULT, WPARAM};
use windows::Win32::UI::Shell::{SHAppBarMessage, ABE_BOTTOM, ABE_TOP, ABM_NEW, ABM_REMOVE, ABM_SETPOS, APPBARDATA};
use windows::Win32::UI::WindowsAndMessaging::{
CallWindowProcW, DefWindowProcW, SetWindowLongPtrW, SetWindowPos, ShowWindow, GWL_EXSTYLE, HWND_NOTOPMOST,
SWP_NOSENDCHANGING, SWP_NOSIZE, SW_RESTORE, WM_SIZE, WS_EX_NOACTIVATE,
Expand Down Expand Up @@ -91,7 +92,7 @@ fn setup_window_size(
Ok(())
}

fn setup_window_surface(window: Window, geometry: &MonitorGeometry) -> anyhow::Result<()> {
fn get_hwnd(window: &Window) -> windows::Win32::Foundation::HWND {
// https://discourse.gnome.org/t/set-absolut-window-position-in-gtk4/8552/4
let native = window.native().expect("Failed to get native");
let surface = native.surface().expect("Failed to get surface");
Expand All @@ -101,19 +102,52 @@ fn setup_window_surface(window: Window, geometry: &MonitorGeometry) -> anyhow::R
.downcast::<gdk4_win32::Win32Surface>()
.expect("Failed to get Win32Surface")
.handle();
let hwnd = windows::Win32::Foundation::HWND(handle.0);
windows::Win32::Foundation::HWND(handle.0)
}

fn setup_window_surface(
window: &Window,
geometry: &MonitorGeometry,
scale_factor: &MonitorScaleFactor,
offset_x: i32,
offset_y: i32,
position: &BarPosition,
) -> anyhow::Result<()> {
let height = ((geometry.height + offset_y) as f32) as i32;
let width = ((geometry.width + offset_x) as f32) as i32;
let u_edge = match position {
BarPosition::Top => ABE_TOP,
BarPosition::Bottom => ABE_BOTTOM,
};

let rc = windows::Win32::Foundation::RECT {
left: geometry.x,
right: geometry.x + width,
top: geometry.y,
bottom: geometry.y + height,
};

let hwnd = get_hwnd(window);
let mut appbar_data = APPBARDATA {
hWnd: hwnd,
rc,
uEdge: u_edge,
..Default::default()
};

unsafe {
SHAppBarMessage(ABM_NEW, &mut appbar_data);
SHAppBarMessage(ABM_SETPOS, &mut appbar_data);

SetWindowPos(
hwnd, // TODO @codyduong, set this up for user configuration
hwnd,
HWND_NOTOPMOST,
geometry.x,
geometry.y,
0,
0,
SWP_NOSIZE | SWP_NOSENDCHANGING,
)
.ok();
)?;
SetWindowLongPtrW(hwnd, GWL_EXSTYLE, WS_EX_NOACTIVATE.0 as _);
// TODO @codyduong setup preventing movement via live-caption or other movements
// let original_wnd_proc = std::mem::transmute(GetWindowLongPtrW(hwnd, GWLP_WNDPROC));
Expand All @@ -124,6 +158,19 @@ fn setup_window_surface(window: Window, geometry: &MonitorGeometry) -> anyhow::R
Ok(())
}

fn shutdown_window_surface(window: &Window) -> () {
let hwnd = get_hwnd(window);

let mut appbar_data = APPBARDATA {
hWnd: hwnd,
..Default::default()
};

unsafe { SHAppBarMessage(ABM_REMOVE, &mut appbar_data) };

()
}

#[derive(Debug)]
pub enum BarLuaHook {
BoxHook(BoxMsgHook),
Expand Down Expand Up @@ -158,7 +205,7 @@ pub struct BarProps {
}

pub struct Bar {
position: Option<BarPosition>,
position: BarPosition,
geometry: MonitorGeometry,
index: usize,
scale_factor: MonitorScaleFactor,
Expand Down Expand Up @@ -199,35 +246,36 @@ impl Component for Bar {

connect_show => move |window| {
// Surfaces aren't ready in realize, but they are ready for consumption here
let _ = setup_window_surface(window.clone(), &model.geometry);
let _ = setup_window_surface(&window, &model.geometry, &model.scale_factor, model.offset_x, model.offset_y, &model.position);
// regardless of win version komorebi is consistent unlike gdk4
let height = ((model.geometry.height + model.offset_y) as f32 * model.scale_factor.y) as i32;
// let height = ((model.geometry.height + model.offset_y) as f32 * model.scale_factor.y) as i32;

// println!("{:?} {:?}", (model.geometry.height + &model.offset_y), height);

if model.position.is_some_and(|pos| pos == BarPosition::Bottom) {
let _ = komorebi_client::send_message(&komorebi_client::SocketMessage::MonitorWorkAreaOffset(
model.index,
komorebi_client::Rect { left: 0, top: 0, right: 0, bottom: height }
));
} else {
let _ = komorebi_client::send_message(&komorebi_client::SocketMessage::MonitorWorkAreaOffset(
model.index,
komorebi_client::Rect { left: 0, top: height, right: 0, bottom: height }
));
}
// if model.position.is_some_and(|pos| pos == BarPosition::Bottom) {
// let _ = komorebi_client::send_message(&komorebi_client::SocketMessage::MonitorWorkAreaOffset(
// model.index,
// komorebi_client::Rect { left: 0, top: 0, right: 0, bottom: height }
// ));
// } else {
// let _ = komorebi_client::send_message(&komorebi_client::SocketMessage::MonitorWorkAreaOffset(
// model.index,
// komorebi_client::Rect { left: 0, top: height, right: 0, bottom: height }
// ));
// }
},

connect_unrealize => move |_window| {
let _ = komorebi_client::send_message(&komorebi_client::SocketMessage::MonitorWorkAreaOffset(
model.index,
komorebi_client::Rect {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
));
connect_unrealize => move |window| {
// let _ = komorebi_client::send_message(&komorebi_client::SocketMessage::MonitorWorkAreaOffset(
// model.index,
// komorebi_client::Rect {
// left: 0,
// top: 0,
// right: 0,
// bottom: 0,
// },
// ));
shutdown_window_surface(window);
},
}
}
Expand All @@ -238,15 +286,18 @@ impl Component for Bar {
callback(sender.clone().input_sender().clone());

let mut geometry = monitor.geometry;
let position = props.position.unwrap_or(BarPosition::Top);

let mut offset_x = 0;
let mut offset_y = 0;

// by default use 32
// TODO @codyduong, this is assuming a horizontal bar, otherwise change defaults
geometry.height = crate::common::HITOKAGE_STATUSBAR_HEIGHT;

geometry.width = props.width.unwrap_or(geometry.width);
geometry.height = props.height.unwrap_or(geometry.height);
geometry.height = props.height.unwrap_or(crate::common::HITOKAGE_STATUSBAR_HEIGHT);

match position {
BarPosition::Top => (),
BarPosition::Bottom => geometry.y += monitor.geometry.height - geometry.height,
};

if let Some(offset) = props.offset {
if let Some(x) = offset.x {
Expand All @@ -260,7 +311,7 @@ impl Component for Bar {
}

let mut model = Bar {
position: props.position,
position,
geometry,
index: monitor.index,
scale_factor: monitor.scale_factor,
Expand Down
4 changes: 4 additions & 0 deletions hitokage-lua-lib/library/components/bar.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
---@meta hitokage.components.bar

---TODO don't use, the behavior of this is not well decided and subject to change
---@class BarOffset
---@field x integer?
---@field y integer?

-- ---@alias BarPosition 'Top' | 'Bottom'

--------------------------------------------------------------------------------

---Used as entrypoint for <!--@mkdocs-ignore-start-->[`monitor:attach`](lua://Monitor.attach)<!--@mkdocs-ignore-end-->
Expand Down Expand Up @@ -37,6 +40,7 @@
---@field width integer?
---@field height integer?
---@field offset BarOffset?
-- ---@field position BarPosition?

--------------------------------------------------------------------------------
---Links to BarUserData in 'hitokage-lua\src\components\bar.rs'
Expand Down

0 comments on commit 56a9a48

Please sign in to comment.