mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-01 02:31:04 +02:00
fix: popup placement issues
This commit is contained in:
parent
8518262053
commit
8576ac5c44
7 changed files with 54 additions and 66 deletions
14
src/bar.rs
14
src/bar.rs
|
@ -31,7 +31,7 @@ pub fn create_bar(app: &Application, monitor: &Monitor, monitor_name: &str, conf
|
|||
content.set_center_widget(Some(¢er));
|
||||
content.pack_end(&right, false, false, 0);
|
||||
|
||||
load_modules(&left, ¢er, &right, app, config, monitor_name);
|
||||
load_modules(&left, ¢er, &right, app, config, monitor, monitor_name);
|
||||
win.add(&content);
|
||||
|
||||
win.connect_destroy_event(|_, _| {
|
||||
|
@ -48,6 +48,7 @@ fn load_modules(
|
|||
right: >k::Box,
|
||||
app: &Application,
|
||||
config: Config,
|
||||
monitor: &Monitor,
|
||||
output_name: &str,
|
||||
) {
|
||||
if let Some(modules) = config.left {
|
||||
|
@ -55,10 +56,11 @@ fn load_modules(
|
|||
app,
|
||||
location: ModuleLocation::Left,
|
||||
bar_position: &config.position,
|
||||
monitor,
|
||||
output_name,
|
||||
};
|
||||
|
||||
add_modules(left, modules, info);
|
||||
add_modules(left, modules, &info);
|
||||
}
|
||||
|
||||
if let Some(modules) = config.center {
|
||||
|
@ -66,10 +68,11 @@ fn load_modules(
|
|||
app,
|
||||
location: ModuleLocation::Center,
|
||||
bar_position: &config.position,
|
||||
monitor,
|
||||
output_name,
|
||||
};
|
||||
|
||||
add_modules(center, modules, info);
|
||||
add_modules(center, modules, &info);
|
||||
}
|
||||
|
||||
if let Some(modules) = config.right {
|
||||
|
@ -77,14 +80,15 @@ fn load_modules(
|
|||
app,
|
||||
location: ModuleLocation::Right,
|
||||
bar_position: &config.position,
|
||||
monitor,
|
||||
output_name,
|
||||
};
|
||||
|
||||
add_modules(right, modules, info);
|
||||
add_modules(right, modules, &info);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_modules(content: >k::Box, modules: Vec<ModuleConfig>, info: ModuleInfo) {
|
||||
fn add_modules(content: >k::Box, modules: Vec<ModuleConfig>, info: &ModuleInfo) {
|
||||
macro_rules! add_module {
|
||||
($module:expr, $name:literal) => {{
|
||||
let widget = $module.into_widget(&info);
|
||||
|
|
|
@ -2,7 +2,6 @@ mod popup;
|
|||
|
||||
use self::popup::Popup;
|
||||
use crate::modules::{Module, ModuleInfo};
|
||||
use crate::popup::PopupAlignment;
|
||||
use chrono::Local;
|
||||
use glib::Continue;
|
||||
use gtk::prelude::*;
|
||||
|
@ -33,6 +32,7 @@ impl Module<Button> for ClockModule {
|
|||
let popup = Popup::new(
|
||||
"popup-clock",
|
||||
info.app,
|
||||
info.monitor,
|
||||
Orientation::Vertical,
|
||||
info.bar_position,
|
||||
);
|
||||
|
@ -41,14 +41,7 @@ impl Module<Button> for ClockModule {
|
|||
button.show_all();
|
||||
|
||||
button.connect_clicked(move |button| {
|
||||
let button_w = button.allocation().width();
|
||||
|
||||
let (button_x, _) = button
|
||||
.translate_coordinates(&button.toplevel().unwrap(), 0, 0)
|
||||
.unwrap();
|
||||
|
||||
popup.show();
|
||||
popup.set_pos(f64::from(button_x + button_w), PopupAlignment::Right);
|
||||
popup.show(button);
|
||||
});
|
||||
|
||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||
|
|
|
@ -2,7 +2,6 @@ use crate::collection::Collection;
|
|||
use crate::icon::{find_desktop_file, get_icon};
|
||||
use crate::modules::launcher::popup::Popup;
|
||||
use crate::modules::launcher::FocusEvent;
|
||||
use crate::popup::PopupAlignment;
|
||||
use crate::sway::SwayNode;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Button, IconTheme, Image};
|
||||
|
@ -175,19 +174,8 @@ impl LauncherItem {
|
|||
button.connect_enter_notify_event(move |button, _| {
|
||||
let windows = windows.lock().unwrap();
|
||||
if windows.len() > 1 {
|
||||
let button_w = button.allocation().width();
|
||||
|
||||
let (button_x, _) = button
|
||||
.translate_coordinates(&button.toplevel().unwrap(), 0, 0)
|
||||
.unwrap();
|
||||
|
||||
let button_center = f64::from(button_x) + f64::from(button_w) / 2.0;
|
||||
|
||||
popup.set_windows(windows.as_slice(), &tx_hover);
|
||||
popup.show();
|
||||
|
||||
// TODO: Pass through module location
|
||||
popup.set_pos(button_center, PopupAlignment::Center);
|
||||
popup.show(button);
|
||||
}
|
||||
|
||||
Inhibit(false)
|
||||
|
|
|
@ -194,6 +194,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
let popup = Popup::new(
|
||||
"popup-launcher",
|
||||
info.app,
|
||||
info.monitor,
|
||||
Orientation::Vertical,
|
||||
info.bar_position,
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::config::BarPosition;
|
|||
/// Shamelessly stolen from here:
|
||||
/// <https://github.com/zeroeightysix/rustbar/blob/master/src/modules/module.rs>
|
||||
use glib::IsA;
|
||||
use gtk::gdk::Monitor;
|
||||
use gtk::{Application, Widget};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde_json::Value;
|
||||
|
@ -32,6 +33,7 @@ pub struct ModuleInfo<'a> {
|
|||
pub app: &'a Application,
|
||||
pub location: ModuleLocation,
|
||||
pub bar_position: &'a BarPosition,
|
||||
pub monitor: &'a Monitor,
|
||||
pub output_name: &'a str,
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ use self::popup::Popup;
|
|||
use crate::modules::mpd::client::{get_connection, get_duration, get_elapsed};
|
||||
use crate::modules::mpd::popup::{MpdPopup, PopupEvent};
|
||||
use crate::modules::{Module, ModuleInfo};
|
||||
use crate::popup::PopupAlignment;
|
||||
use dirs::home_dir;
|
||||
use glib::Continue;
|
||||
use gtk::prelude::*;
|
||||
|
@ -80,7 +79,7 @@ fn get_tokens(re: &Regex, format_string: &str) -> Vec<String> {
|
|||
}
|
||||
|
||||
enum Event {
|
||||
Open(f64),
|
||||
Open,
|
||||
Update(Box<Option<(Song, Status, String)>>),
|
||||
}
|
||||
|
||||
|
@ -96,6 +95,7 @@ impl Module<Button> for MpdModule {
|
|||
let popup = Popup::new(
|
||||
"popup-mpd",
|
||||
info.app,
|
||||
info.monitor,
|
||||
Orientation::Horizontal,
|
||||
info.bar_position,
|
||||
);
|
||||
|
@ -106,16 +106,8 @@ impl Module<Button> for MpdModule {
|
|||
|
||||
let music_dir = self.music_dir.clone();
|
||||
|
||||
button.connect_clicked(move |button| {
|
||||
let button_w = button.allocation().width();
|
||||
|
||||
let (button_x, _) = button
|
||||
.translate_coordinates(&button.toplevel().unwrap(), 0, 0)
|
||||
.unwrap();
|
||||
|
||||
click_tx
|
||||
.send(Event::Open(f64::from(button_x + button_w)))
|
||||
.unwrap();
|
||||
button.connect_clicked(move |_| {
|
||||
click_tx.send(Event::Open).unwrap();
|
||||
});
|
||||
|
||||
let host = self.host.clone();
|
||||
|
@ -167,9 +159,8 @@ impl Module<Button> for MpdModule {
|
|||
|
||||
rx.attach(None, move |event| {
|
||||
match event {
|
||||
Event::Open(pos) => {
|
||||
mpd_popup.popup.show();
|
||||
mpd_popup.popup.set_pos(pos, PopupAlignment::Right);
|
||||
Event::Open => {
|
||||
mpd_popup.popup.show(&button);
|
||||
}
|
||||
Event::Update(mut msg) => {
|
||||
if let Some((song, status, string)) = msg.take() {
|
||||
|
@ -220,7 +211,7 @@ impl MpdModule {
|
|||
PlayState::Playing => self.icon_play.as_ref(),
|
||||
PlayState::Paused => self.icon_pause.as_ref(),
|
||||
};
|
||||
icon.map(|i| i.as_str())
|
||||
icon.map(String::as_str)
|
||||
}
|
||||
"title" => song.title(),
|
||||
"album" => try_get_first_tag(song.tags.get(&Tag::Album)),
|
||||
|
|
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