mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-20 07:41:25 +02:00
feat(bar): dpi-awareness + position hotloading
This commit ensures that the komorebi-bar.exe process is DPI aware and applies DPI compensation to viewport.position and viewport.inner size both on launch and on configuration reload. viewport.position changes are now hotloaded wihtout having to restart the process. re #1024
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -501,6 +501,12 @@ version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "atomic_float"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628d228f918ac3b82fe590352cc719d30664a0c13ca3a60266fe02c7132d480a"
|
||||
|
||||
[[package]]
|
||||
name = "atspi"
|
||||
version = "0.19.0"
|
||||
@@ -2705,6 +2711,7 @@ dependencies = [
|
||||
name = "komorebi-bar"
|
||||
version = "0.1.30"
|
||||
dependencies = [
|
||||
"atomic_float",
|
||||
"chrono",
|
||||
"clap",
|
||||
"color-eyre",
|
||||
|
||||
@@ -9,6 +9,7 @@ edition = "2021"
|
||||
komorebi-client = { path = "../komorebi-client" }
|
||||
komorebi-themes = { path = "../komorebi-themes" }
|
||||
|
||||
atomic_float = "1"
|
||||
chrono = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::komorebi::Komorebi;
|
||||
use crate::komorebi::KomorebiNotificationState;
|
||||
use crate::widget::BarWidget;
|
||||
use crate::widget::WidgetConfig;
|
||||
use crate::DPI;
|
||||
use crate::MAX_LABEL_WIDTH;
|
||||
use crossbeam_channel::Receiver;
|
||||
use eframe::egui::Align;
|
||||
@@ -17,6 +18,7 @@ use eframe::egui::FontId;
|
||||
use eframe::egui::Frame;
|
||||
use eframe::egui::Layout;
|
||||
use eframe::egui::Margin;
|
||||
use eframe::egui::Pos2;
|
||||
use eframe::egui::Style;
|
||||
use eframe::egui::TextStyle;
|
||||
use eframe::egui::Vec2;
|
||||
@@ -145,12 +147,14 @@ impl Komobar {
|
||||
}
|
||||
|
||||
if let Some(viewport) = &config.viewport {
|
||||
if let Some(inner_size) = viewport.inner_size {
|
||||
let mut vec2 = Vec2::new(inner_size.x, inner_size.y * 2.0);
|
||||
if self.scale_factor != 1.0 {
|
||||
vec2 = Vec2::new(inner_size.x / self.scale_factor, inner_size.y * 2.0);
|
||||
}
|
||||
let dpi = DPI.load(Ordering::SeqCst);
|
||||
if let Some(position) = viewport.position {
|
||||
let pos2 = Pos2::new(position.x / dpi, position.y / dpi);
|
||||
ctx.send_viewport_cmd(ViewportCommand::OuterPosition(pos2));
|
||||
}
|
||||
|
||||
if let Some(position) = viewport.inner_size {
|
||||
let vec2 = Vec2::new(position.x / dpi, position.y / dpi);
|
||||
ctx.send_viewport_cmd(ViewportCommand::InnerSize(vec2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,9 @@ mod widget;
|
||||
use crate::bar::Komobar;
|
||||
use crate::config::KomobarConfig;
|
||||
use crate::config::Position;
|
||||
use atomic_float::AtomicF32;
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::bail;
|
||||
use eframe::egui::ViewportBuilder;
|
||||
use font_loader::system_fonts;
|
||||
use hotwatch::EventKind;
|
||||
@@ -25,12 +27,16 @@ use std::io::BufReader;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::AtomicI32;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use windows::Win32::UI::HiDpi::SetProcessDpiAwarenessContext;
|
||||
use windows::Win32::UI::HiDpi::DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2;
|
||||
|
||||
pub static WIDGET_SPACING: f32 = 10.0;
|
||||
pub static MAX_LABEL_WIDTH: AtomicI32 = AtomicI32::new(400);
|
||||
pub static DPI: AtomicF32 = AtomicF32::new(1.0);
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(author, about, version)]
|
||||
@@ -49,7 +55,39 @@ struct Opts {
|
||||
quickstart: bool,
|
||||
}
|
||||
|
||||
macro_rules! as_ptr {
|
||||
($value:expr) => {
|
||||
$value as *mut core::ffi::c_void
|
||||
};
|
||||
}
|
||||
|
||||
pub fn dpi_for_monitor(hmonitor: isize) -> color_eyre::Result<f32> {
|
||||
use windows::Win32::Graphics::Gdi::HMONITOR;
|
||||
use windows::Win32::UI::HiDpi::GetDpiForMonitor;
|
||||
use windows::Win32::UI::HiDpi::MDT_EFFECTIVE_DPI;
|
||||
|
||||
let mut dpi_x = u32::default();
|
||||
let mut dpi_y = u32::default();
|
||||
|
||||
unsafe {
|
||||
match GetDpiForMonitor(
|
||||
HMONITOR(as_ptr!(hmonitor)),
|
||||
MDT_EFFECTIVE_DPI,
|
||||
std::ptr::addr_of_mut!(dpi_x),
|
||||
std::ptr::addr_of_mut!(dpi_y),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(error) => bail!(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
Ok(dpi_y as f32 / 96.0)
|
||||
}
|
||||
|
||||
fn main() -> color_eyre::Result<()> {
|
||||
unsafe { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) }?;
|
||||
|
||||
let opts: Opts = Opts::parse();
|
||||
|
||||
if opts.schema {
|
||||
@@ -157,30 +195,39 @@ fn main() -> color_eyre::Result<()> {
|
||||
&SocketMessage::State,
|
||||
)?)?;
|
||||
|
||||
let dpi = dpi_for_monitor(state.monitors.elements()[config.monitor.index].id())?;
|
||||
DPI.store(dpi, Ordering::SeqCst);
|
||||
|
||||
let mut viewport_builder = ViewportBuilder::default()
|
||||
.with_decorations(false)
|
||||
// .with_transparent(config.transparent)
|
||||
.with_taskbar(false)
|
||||
.with_position(Position {
|
||||
x: state.monitors.elements()[config.monitor.index].size().left as f32,
|
||||
y: state.monitors.elements()[config.monitor.index].size().top as f32,
|
||||
x: state.monitors.elements()[config.monitor.index].size().left as f32 / dpi,
|
||||
y: state.monitors.elements()[config.monitor.index].size().top as f32 / dpi,
|
||||
})
|
||||
.with_inner_size({
|
||||
Position {
|
||||
x: state.monitors.elements()[config.monitor.index].size().right as f32,
|
||||
y: 20.0,
|
||||
x: state.monitors.elements()[config.monitor.index].size().right as f32 / dpi,
|
||||
y: 50.0 / dpi,
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(viewport) = &config.viewport {
|
||||
if let Some(position) = &viewport.position {
|
||||
if let Some(mut position) = &viewport.position {
|
||||
position.x /= dpi;
|
||||
position.y /= dpi;
|
||||
|
||||
let b = viewport_builder.clone();
|
||||
viewport_builder = b.with_position(*position);
|
||||
viewport_builder = b.with_position(position);
|
||||
}
|
||||
|
||||
if let Some(inner_size) = &viewport.inner_size {
|
||||
if let Some(mut inner_size) = &viewport.inner_size {
|
||||
inner_size.x /= dpi;
|
||||
inner_size.y /= dpi;
|
||||
|
||||
let b = viewport_builder.clone();
|
||||
viewport_builder = b.with_inner_size(*inner_size);
|
||||
viewport_builder = b.with_inner_size(inner_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user