mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-03 19:51:03 +02:00
fix: popup placement issues
This commit is contained in:
parent
8518262053
commit
8576ac5c44
7 changed files with 54 additions and 66 deletions
55
src/popup.rs
55
src/popup.rs
|
@ -1,23 +1,20 @@
|
|||
use crate::config::BarPosition;
|
||||
use gtk::gdk::Monitor;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Application, ApplicationWindow, Orientation};
|
||||
use gtk::{Application, ApplicationWindow, Button, Orientation};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Popup {
|
||||
pub window: ApplicationWindow,
|
||||
pub container: gtk::Box,
|
||||
}
|
||||
|
||||
pub enum PopupAlignment {
|
||||
Left,
|
||||
Center,
|
||||
Right,
|
||||
monitor: Monitor,
|
||||
}
|
||||
|
||||
impl Popup {
|
||||
pub fn new(
|
||||
name: &str,
|
||||
app: &Application,
|
||||
monitor: &Monitor,
|
||||
orientation: Orientation,
|
||||
bar_position: &BarPosition,
|
||||
) -> Self {
|
||||
|
@ -72,11 +69,11 @@ impl Popup {
|
|||
win.add(&content);
|
||||
|
||||
win.connect_leave_notify_event(|win, ev| {
|
||||
const THRESHOLD: f64 = 3.0;
|
||||
|
||||
let (w, _h) = win.size();
|
||||
let (x, y) = ev.position();
|
||||
|
||||
const THRESHOLD: f64 = 3.0;
|
||||
|
||||
// some child widgets trigger this event
|
||||
// so check we're actually outside the window
|
||||
if x < THRESHOLD || y < THRESHOLD || x > f64::from(w) - THRESHOLD {
|
||||
|
@ -89,29 +86,41 @@ impl Popup {
|
|||
Self {
|
||||
window: win,
|
||||
container: content,
|
||||
monitor: monitor.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the popover's X position relative to the left border of the screen
|
||||
pub fn set_pos(&self, pos: f64, alignment: PopupAlignment) {
|
||||
let width = self.window.allocated_width();
|
||||
|
||||
let offset = match alignment {
|
||||
PopupAlignment::Left => pos,
|
||||
PopupAlignment::Center => (pos - (f64::from(width) / 2.0)).round(),
|
||||
PopupAlignment::Right => pos - f64::from(width),
|
||||
};
|
||||
|
||||
gtk_layer_shell::set_margin(&self.window, gtk_layer_shell::Edge::Left, offset as i32);
|
||||
}
|
||||
|
||||
/// Shows the popover
|
||||
pub fn show(&self) {
|
||||
pub fn show(&self, button: &Button) {
|
||||
self.window.show_all();
|
||||
self.set_pos(button);
|
||||
}
|
||||
|
||||
/// Hides the popover
|
||||
pub fn hide(&self) {
|
||||
self.window.hide();
|
||||
}
|
||||
|
||||
/// Sets the popover's X position relative to the left border of the screen
|
||||
fn set_pos(&self, button: &Button) {
|
||||
let widget_width = button.allocation().width();
|
||||
let screen_width = self.monitor.workarea().width();
|
||||
let popup_width = self.window.allocated_width();
|
||||
|
||||
let (widget_x, _) = button
|
||||
.translate_coordinates(&button.toplevel().unwrap(), 0, 0)
|
||||
.unwrap();
|
||||
|
||||
let widget_center = f64::from(widget_x) + f64::from(widget_width) / 2.0;
|
||||
|
||||
let mut offset = (widget_center - (f64::from(popup_width) / 2.0)).round();
|
||||
|
||||
if offset < 5.0 {
|
||||
offset = 5.0;
|
||||
} else if offset > f64::from(screen_width - popup_width) - 5.0 {
|
||||
offset = f64::from(screen_width - popup_width) - 5.0;
|
||||
}
|
||||
|
||||
gtk_layer_shell::set_margin(&self.window, gtk_layer_shell::Edge::Left, offset as i32);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue