mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-01 18:51:04 +02:00
Merge pull request #459 from JakeStanger/fix/popup-resize
fix(popup): re-position on resize due to content change
This commit is contained in:
commit
180a5205b9
12 changed files with 114 additions and 81 deletions
17
src/bar.rs
17
src/bar.rs
|
@ -10,7 +10,6 @@ use gtk::gdk::Monitor;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Application, ApplicationWindow, IconTheme, Orientation, Window, WindowType};
|
use gtk::{Application, ApplicationWindow, IconTheme, Orientation, Window, WindowType};
|
||||||
use gtk_layer_shell::LayerShell;
|
use gtk_layer_shell::LayerShell;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
@ -18,7 +17,7 @@ use tracing::{debug, info};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum Inner {
|
enum Inner {
|
||||||
New { config: Option<Config> },
|
New { config: Option<Config> },
|
||||||
Loaded { popup: Rc<RefCell<Popup>> },
|
Loaded { popup: Rc<Popup> },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -60,7 +59,7 @@ impl Bar {
|
||||||
window.set_widget_name(&name);
|
window.set_widget_name(&name);
|
||||||
|
|
||||||
let position = config.position;
|
let position = config.position;
|
||||||
let orientation = position.get_orientation();
|
let orientation = position.orientation();
|
||||||
|
|
||||||
let content = gtk::Box::builder()
|
let content = gtk::Box::builder()
|
||||||
.orientation(orientation)
|
.orientation(orientation)
|
||||||
|
@ -187,7 +186,7 @@ impl Bar {
|
||||||
win.set_layer_shell_margin(gtk_layer_shell::Edge::Left, margin.left);
|
win.set_layer_shell_margin(gtk_layer_shell::Edge::Left, margin.left);
|
||||||
win.set_layer_shell_margin(gtk_layer_shell::Edge::Right, margin.right);
|
win.set_layer_shell_margin(gtk_layer_shell::Edge::Right, margin.right);
|
||||||
|
|
||||||
let bar_orientation = position.get_orientation();
|
let bar_orientation = position.orientation();
|
||||||
|
|
||||||
win.set_anchor(
|
win.set_anchor(
|
||||||
gtk_layer_shell::Edge::Top,
|
gtk_layer_shell::Edge::Top,
|
||||||
|
@ -269,7 +268,7 @@ impl Bar {
|
||||||
|
|
||||||
// popup ignores module location so can bodge this for now
|
// popup ignores module location so can bodge this for now
|
||||||
let popup = Popup::new(&info!(ModuleLocation::Left), config.popup_gap);
|
let popup = Popup::new(&info!(ModuleLocation::Left), config.popup_gap);
|
||||||
let popup = Rc::new(RefCell::new(popup));
|
let popup = Rc::new(popup);
|
||||||
|
|
||||||
if let Some(modules) = config.start {
|
if let Some(modules) = config.start {
|
||||||
let info = info!(ModuleLocation::Left);
|
let info = info!(ModuleLocation::Left);
|
||||||
|
@ -315,7 +314,7 @@ impl Bar {
|
||||||
&self.monitor_name
|
&self.monitor_name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn popup(&self) -> Rc<RefCell<Popup>> {
|
pub fn popup(&self) -> Rc<Popup> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
Inner::New { .. } => {
|
Inner::New { .. } => {
|
||||||
panic!("Attempted to get popup of uninitialized bar. This is a serious bug!")
|
panic!("Attempted to get popup of uninitialized bar. This is a serious bug!")
|
||||||
|
@ -339,7 +338,7 @@ fn create_container(name: &str, orientation: Orientation) -> gtk::Box {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BarLoadResult {
|
struct BarLoadResult {
|
||||||
popup: Rc<RefCell<Popup>>,
|
popup: Rc<Popup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds modules into a provided GTK box,
|
/// Adds modules into a provided GTK box,
|
||||||
|
@ -349,9 +348,9 @@ fn add_modules(
|
||||||
modules: Vec<ModuleConfig>,
|
modules: Vec<ModuleConfig>,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
ironbar: &Rc<Ironbar>,
|
ironbar: &Rc<Ironbar>,
|
||||||
popup: &Rc<RefCell<Popup>>,
|
popup: &Rc<Popup>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let orientation = info.bar_position.get_orientation();
|
let orientation = info.bar_position.orientation();
|
||||||
|
|
||||||
macro_rules! add_module {
|
macro_rules! add_module {
|
||||||
($module:expr, $id:expr) => {{
|
($module:expr, $id:expr) => {{
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl<'de> Deserialize<'de> for MonitorConfig {
|
||||||
impl BarPosition {
|
impl BarPosition {
|
||||||
/// Gets the orientation the bar and widgets should use
|
/// Gets the orientation the bar and widgets should use
|
||||||
/// based on this position.
|
/// based on this position.
|
||||||
pub fn get_orientation(self) -> Orientation {
|
pub fn orientation(self) -> Orientation {
|
||||||
if self == Self::Top || self == Self::Bottom {
|
if self == Self::Top || self == Self::Bottom {
|
||||||
Orientation::Horizontal
|
Orientation::Horizontal
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -167,13 +167,13 @@ impl Ipc {
|
||||||
match bar {
|
match bar {
|
||||||
Some(bar) => {
|
Some(bar) => {
|
||||||
let popup = bar.popup();
|
let popup = bar.popup();
|
||||||
let current_widget = popup.borrow().current_widget();
|
let current_widget = popup.current_widget();
|
||||||
|
|
||||||
popup.borrow_mut().hide();
|
popup.hide();
|
||||||
|
|
||||||
let data = popup
|
let data = popup
|
||||||
.borrow()
|
|
||||||
.cache
|
.cache
|
||||||
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, value)| value.name == name)
|
.find(|(_, value)| value.name == name)
|
||||||
.map(|(id, value)| (*id, value.content.buttons.first().cloned()));
|
.map(|(id, value)| (*id, value.content.buttons.first().cloned()));
|
||||||
|
@ -181,7 +181,6 @@ impl Ipc {
|
||||||
match data {
|
match data {
|
||||||
Some((id, Some(button))) if current_widget != Some(id) => {
|
Some((id, Some(button))) if current_widget != Some(id) => {
|
||||||
let button_id = button.popup_id();
|
let button_id = button.popup_id();
|
||||||
let mut popup = popup.borrow_mut();
|
|
||||||
|
|
||||||
if popup.is_visible() {
|
if popup.is_visible() {
|
||||||
popup.hide();
|
popup.hide();
|
||||||
|
@ -207,11 +206,11 @@ impl Ipc {
|
||||||
let popup = bar.popup();
|
let popup = bar.popup();
|
||||||
|
|
||||||
// only one popup per bar, so hide if open for another widget
|
// only one popup per bar, so hide if open for another widget
|
||||||
popup.borrow_mut().hide();
|
popup.hide();
|
||||||
|
|
||||||
let data = popup
|
let data = popup
|
||||||
.borrow()
|
|
||||||
.cache
|
.cache
|
||||||
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, value)| value.name == name)
|
.find(|(_, value)| value.name == name)
|
||||||
.map(|(id, value)| (*id, value.content.buttons.first().cloned()));
|
.map(|(id, value)| (*id, value.content.buttons.first().cloned()));
|
||||||
|
@ -219,7 +218,7 @@ impl Ipc {
|
||||||
match data {
|
match data {
|
||||||
Some((id, Some(button))) => {
|
Some((id, Some(button))) => {
|
||||||
let button_id = button.popup_id();
|
let button_id = button.popup_id();
|
||||||
popup.borrow_mut().show(id, button_id);
|
popup.show(id, button_id);
|
||||||
|
|
||||||
Response::Ok
|
Response::Ok
|
||||||
}
|
}
|
||||||
|
@ -236,7 +235,7 @@ impl Ipc {
|
||||||
match bar {
|
match bar {
|
||||||
Some(bar) => {
|
Some(bar) => {
|
||||||
let popup = bar.popup();
|
let popup = bar.popup();
|
||||||
popup.borrow_mut().hide();
|
popup.hide();
|
||||||
|
|
||||||
Response::Ok
|
Response::Ok
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ impl Module<gtk::Box> for CustomModule {
|
||||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
) -> Result<ModuleParts<gtk::Box>> {
|
) -> Result<ModuleParts<gtk::Box>> {
|
||||||
let orientation = info.bar_position.get_orientation();
|
let orientation = info.bar_position.orientation();
|
||||||
let container = gtk::Box::builder().orientation(orientation).build();
|
let container = gtk::Box::builder().orientation(orientation).build();
|
||||||
|
|
||||||
let popup_buttons = Rc::new(RefCell::new(Vec::new()));
|
let popup_buttons = Rc::new(RefCell::new(Vec::new()));
|
||||||
|
@ -236,7 +236,7 @@ impl Module<gtk::Box> for CustomModule {
|
||||||
if let Some(popup) = self.popup {
|
if let Some(popup) = self.popup {
|
||||||
let custom_context = CustomWidgetContext {
|
let custom_context = CustomWidgetContext {
|
||||||
tx: &tx,
|
tx: &tx,
|
||||||
bar_orientation: info.bar_position.get_orientation(),
|
bar_orientation: info.bar_position.orientation(),
|
||||||
icon_theme: info.icon_theme,
|
icon_theme: info.icon_theme,
|
||||||
popup_buttons: Rc::new(RefCell::new(vec![])),
|
popup_buttons: Rc::new(RefCell::new(vec![])),
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl Module<gtk::Box> for FocusedModule {
|
||||||
) -> Result<ModuleParts<gtk::Box>> {
|
) -> Result<ModuleParts<gtk::Box>> {
|
||||||
let icon_theme = info.icon_theme;
|
let icon_theme = info.icon_theme;
|
||||||
|
|
||||||
let container = gtk::Box::new(info.bar_position.get_orientation(), 5);
|
let container = gtk::Box::new(info.bar_position.orientation(), 5);
|
||||||
|
|
||||||
let icon = gtk::Image::new();
|
let icon = gtk::Image::new();
|
||||||
if self.show_icon {
|
if self.show_icon {
|
||||||
|
|
|
@ -225,9 +225,7 @@ impl ItemButton {
|
||||||
|
|
||||||
try_send!(
|
try_send!(
|
||||||
tx,
|
tx,
|
||||||
ModuleUpdateEvent::OpenPopupAt(
|
ModuleUpdateEvent::OpenPopupAt(button.geometry(bar_position.orientation()))
|
||||||
button.geometry(bar_position.get_orientation())
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
try_send!(tx, ModuleUpdateEvent::ClosePopup);
|
try_send!(tx, ModuleUpdateEvent::ClosePopup);
|
||||||
|
|
|
@ -301,7 +301,7 @@ impl Module<gtk::Box> for LauncherModule {
|
||||||
) -> crate::Result<ModuleParts<gtk::Box>> {
|
) -> crate::Result<ModuleParts<gtk::Box>> {
|
||||||
let icon_theme = info.icon_theme;
|
let icon_theme = info.icon_theme;
|
||||||
|
|
||||||
let container = gtk::Box::new(info.bar_position.get_orientation(), 0);
|
let container = gtk::Box::new(info.bar_position.orientation(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
let container = container.clone();
|
let container = container.clone();
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -215,7 +214,7 @@ pub fn create_module<TModule, TWidget, TSend, TRec>(
|
||||||
ironbar: Rc<Ironbar>,
|
ironbar: Rc<Ironbar>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
popup: &Rc<RefCell<Popup>>,
|
popup: &Rc<Popup>,
|
||||||
) -> Result<ModuleParts<TWidget>>
|
) -> Result<ModuleParts<TWidget>>
|
||||||
where
|
where
|
||||||
TModule: Module<TWidget, SendMessage = TSend, ReceiveMessage = TRec>,
|
TModule: Module<TWidget, SendMessage = TSend, ReceiveMessage = TRec>,
|
||||||
|
@ -251,7 +250,7 @@ where
|
||||||
.style_context()
|
.style_context()
|
||||||
.add_class(&format!("popup-{module_name}"));
|
.add_class(&format!("popup-{module_name}"));
|
||||||
|
|
||||||
register_popup_content(popup, id, instance_name, popup_content);
|
popup.register_content(id, instance_name, popup_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_receiver(tx, ui_rx, popup.clone(), module_name, id);
|
setup_receiver(tx, ui_rx, popup.clone(), module_name, id);
|
||||||
|
@ -259,16 +258,6 @@ where
|
||||||
Ok(module_parts)
|
Ok(module_parts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers the popup content with the popup.
|
|
||||||
fn register_popup_content(
|
|
||||||
popup: &Rc<RefCell<Popup>>,
|
|
||||||
id: usize,
|
|
||||||
name: String,
|
|
||||||
popup_content: ModulePopupParts,
|
|
||||||
) {
|
|
||||||
popup.borrow_mut().register_content(id, name, popup_content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets up the bridge channel receiver
|
/// Sets up the bridge channel receiver
|
||||||
/// to pick up events from the controller, widget or popup.
|
/// to pick up events from the controller, widget or popup.
|
||||||
///
|
///
|
||||||
|
@ -277,7 +266,7 @@ fn register_popup_content(
|
||||||
fn setup_receiver<TSend>(
|
fn setup_receiver<TSend>(
|
||||||
tx: broadcast::Sender<TSend>,
|
tx: broadcast::Sender<TSend>,
|
||||||
rx: mpsc::Receiver<ModuleUpdateEvent<TSend>>,
|
rx: mpsc::Receiver<ModuleUpdateEvent<TSend>>,
|
||||||
popup: Rc<RefCell<Popup>>,
|
popup: Rc<Popup>,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
id: usize,
|
id: usize,
|
||||||
) where
|
) where
|
||||||
|
@ -294,7 +283,6 @@ fn setup_receiver<TSend>(
|
||||||
}
|
}
|
||||||
ModuleUpdateEvent::TogglePopup(button_id) => {
|
ModuleUpdateEvent::TogglePopup(button_id) => {
|
||||||
debug!("Toggling popup for {} [#{}]", name, id);
|
debug!("Toggling popup for {} [#{}]", name, id);
|
||||||
let mut popup = popup.borrow_mut();
|
|
||||||
if popup.is_visible() {
|
if popup.is_visible() {
|
||||||
popup.hide();
|
popup.hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -309,8 +297,6 @@ fn setup_receiver<TSend>(
|
||||||
}
|
}
|
||||||
ModuleUpdateEvent::OpenPopup(button_id) => {
|
ModuleUpdateEvent::OpenPopup(button_id) => {
|
||||||
debug!("Opening popup for {} [#{}]", name, id);
|
debug!("Opening popup for {} [#{}]", name, id);
|
||||||
|
|
||||||
let mut popup = popup.borrow_mut();
|
|
||||||
popup.hide();
|
popup.hide();
|
||||||
popup.show(id, button_id);
|
popup.show(id, button_id);
|
||||||
|
|
||||||
|
@ -324,7 +310,6 @@ fn setup_receiver<TSend>(
|
||||||
ModuleUpdateEvent::OpenPopupAt(geometry) => {
|
ModuleUpdateEvent::OpenPopupAt(geometry) => {
|
||||||
debug!("Opening popup for {} [#{}]", name, id);
|
debug!("Opening popup for {} [#{}]", name, id);
|
||||||
|
|
||||||
let mut popup = popup.borrow_mut();
|
|
||||||
popup.hide();
|
popup.hide();
|
||||||
popup.show_at(id, geometry);
|
popup.show_at(id, geometry);
|
||||||
|
|
||||||
|
@ -336,8 +321,6 @@ fn setup_receiver<TSend>(
|
||||||
}
|
}
|
||||||
ModuleUpdateEvent::ClosePopup => {
|
ModuleUpdateEvent::ClosePopup => {
|
||||||
debug!("Closing popup for {} [#{}]", name, id);
|
debug!("Closing popup for {} [#{}]", name, id);
|
||||||
|
|
||||||
let mut popup = popup.borrow_mut();
|
|
||||||
popup.hide();
|
popup.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ impl Module<gtk::Box> for SysInfoModule {
|
||||||
) -> Result<ModuleParts<gtk::Box>> {
|
) -> Result<ModuleParts<gtk::Box>> {
|
||||||
let re = Regex::new(r"\{([^}]+)}")?;
|
let re = Regex::new(r"\{([^}]+)}")?;
|
||||||
|
|
||||||
let container = gtk::Box::new(info.bar_position.get_orientation(), 10);
|
let container = gtk::Box::new(info.bar_position.orientation(), 10);
|
||||||
|
|
||||||
let mut labels = Vec::new();
|
let mut labels = Vec::new();
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl Module<MenuBar> for TrayModule {
|
||||||
let container = MenuBar::new();
|
let container = MenuBar::new();
|
||||||
|
|
||||||
let direction = self.direction.unwrap_or(
|
let direction = self.direction.unwrap_or(
|
||||||
if info.bar_position.get_orientation() == gtk::Orientation::Vertical {
|
if info.bar_position.orientation() == gtk::Orientation::Vertical {
|
||||||
PackDirection::Ttb
|
PackDirection::Ttb
|
||||||
} else {
|
} else {
|
||||||
PackDirection::Ltr
|
PackDirection::Ltr
|
||||||
|
|
|
@ -189,7 +189,7 @@ impl Module<gtk::Box> for WorkspacesModule {
|
||||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
) -> Result<ModuleParts<gtk::Box>> {
|
) -> Result<ModuleParts<gtk::Box>> {
|
||||||
let container = gtk::Box::new(info.bar_position.get_orientation(), 0);
|
let container = gtk::Box::new(info.bar_position.orientation(), 0);
|
||||||
|
|
||||||
let name_map = self.name_map.clone().unwrap_or_default();
|
let name_map = self.name_map.clone().unwrap_or_default();
|
||||||
let favs = self.favorites.clone();
|
let favs = self.favorites.clone();
|
||||||
|
|
120
src/popup.rs
120
src/popup.rs
|
@ -1,11 +1,13 @@
|
||||||
use glib::Propagation;
|
use glib::Propagation;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use gtk::gdk::Monitor;
|
use gtk::gdk::Monitor;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{ApplicationWindow, Orientation};
|
use gtk::{ApplicationWindow, Button, Orientation};
|
||||||
use gtk_layer_shell::LayerShell;
|
use gtk_layer_shell::LayerShell;
|
||||||
use tracing::debug;
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
use crate::config::BarPosition;
|
use crate::config::BarPosition;
|
||||||
use crate::gtk_helpers::{IronbarGtkExt, WidgetGeometry};
|
use crate::gtk_helpers::{IronbarGtkExt, WidgetGeometry};
|
||||||
|
@ -21,10 +23,10 @@ pub struct PopupCacheValue {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Popup {
|
pub struct Popup {
|
||||||
pub window: ApplicationWindow,
|
pub window: ApplicationWindow,
|
||||||
pub cache: HashMap<usize, PopupCacheValue>,
|
pub cache: Rc<RefCell<HashMap<usize, PopupCacheValue>>>,
|
||||||
monitor: Monitor,
|
monitor: Monitor,
|
||||||
pos: BarPosition,
|
pos: BarPosition,
|
||||||
current_widget: Option<usize>,
|
current_widget: Rc<RefCell<Option<(usize, usize)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Popup {
|
impl Popup {
|
||||||
|
@ -33,7 +35,7 @@ impl Popup {
|
||||||
/// and an empty `gtk::Box` container.
|
/// and an empty `gtk::Box` container.
|
||||||
pub fn new(module_info: &ModuleInfo, gap: i32) -> Self {
|
pub fn new(module_info: &ModuleInfo, gap: i32) -> Self {
|
||||||
let pos = module_info.bar_position;
|
let pos = module_info.bar_position;
|
||||||
let orientation = pos.get_orientation();
|
let orientation = pos.orientation();
|
||||||
|
|
||||||
let win = ApplicationWindow::builder()
|
let win = ApplicationWindow::builder()
|
||||||
.application(module_info.app)
|
.application(module_info.app)
|
||||||
|
@ -104,14 +106,14 @@ impl Popup {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
window: win,
|
window: win,
|
||||||
cache: HashMap::new(),
|
cache: Rc::new(RefCell::new(HashMap::new())),
|
||||||
monitor: module_info.monitor.clone(),
|
monitor: module_info.monitor.clone(),
|
||||||
pos,
|
pos,
|
||||||
current_widget: None,
|
current_widget: Rc::new(RefCell::new(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_content(&mut self, key: usize, name: String, content: ModulePopupParts) {
|
pub fn register_content(&self, key: usize, name: String, content: ModulePopupParts) {
|
||||||
debug!("Registered popup content for #{}", key);
|
debug!("Registered popup content for #{}", key);
|
||||||
|
|
||||||
for button in &content.buttons {
|
for button in &content.buttons {
|
||||||
|
@ -119,45 +121,94 @@ impl Popup {
|
||||||
button.set_tag("popup-id", id);
|
button.set_tag("popup-id", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cache.insert(key, PopupCacheValue { name, content });
|
let orientation = self.pos.orientation();
|
||||||
|
let monitor = self.monitor.clone();
|
||||||
|
let window = self.window.clone();
|
||||||
|
|
||||||
|
let current_widget = self.current_widget.clone();
|
||||||
|
let cache = self.cache.clone();
|
||||||
|
|
||||||
|
content
|
||||||
|
.container
|
||||||
|
.connect_size_allocate(move |container, rect| {
|
||||||
|
if container.is_visible() {
|
||||||
|
trace!("Resized: {}x{}", rect.width(), rect.height());
|
||||||
|
|
||||||
|
if let Some((widget_id, button_id)) = *current_widget.borrow() {
|
||||||
|
if let Some(PopupCacheValue { content, .. }) =
|
||||||
|
cache.borrow().get(&widget_id)
|
||||||
|
{
|
||||||
|
Self::set_position(
|
||||||
|
&content.buttons,
|
||||||
|
button_id,
|
||||||
|
orientation,
|
||||||
|
&monitor,
|
||||||
|
&window,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.cache
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(key, PopupCacheValue { name, content });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&mut self, widget_id: usize, button_id: usize) {
|
pub fn show(&self, widget_id: usize, button_id: usize) {
|
||||||
self.clear_window();
|
self.clear_window();
|
||||||
|
|
||||||
if let Some(PopupCacheValue { content, .. }) = self.cache.get(&widget_id) {
|
if let Some(PopupCacheValue { content, .. }) = self.cache.borrow().get(&widget_id) {
|
||||||
self.current_widget = Some(widget_id);
|
*self.current_widget.borrow_mut() = Some((widget_id, button_id));
|
||||||
|
|
||||||
content.container.style_context().add_class("popup");
|
content.container.style_context().add_class("popup");
|
||||||
self.window.add(&content.container);
|
self.window.add(&content.container);
|
||||||
|
|
||||||
self.window.show();
|
self.window.show();
|
||||||
|
|
||||||
let button = content
|
Self::set_position(
|
||||||
.buttons
|
&content.buttons,
|
||||||
.iter()
|
button_id,
|
||||||
.find(|b| b.popup_id() == button_id)
|
self.pos.orientation(),
|
||||||
.expect("to find valid button");
|
&self.monitor,
|
||||||
|
&self.window,
|
||||||
let orientation = self.pos.get_orientation();
|
);
|
||||||
let geometry = button.geometry(orientation);
|
|
||||||
|
|
||||||
self.set_pos(geometry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_at(&self, widget_id: usize, geometry: WidgetGeometry) {
|
pub fn show_at(&self, widget_id: usize, geometry: WidgetGeometry) {
|
||||||
self.clear_window();
|
self.clear_window();
|
||||||
|
|
||||||
if let Some(PopupCacheValue { content, .. }) = self.cache.get(&widget_id) {
|
if let Some(PopupCacheValue { content, .. }) = self.cache.borrow().get(&widget_id) {
|
||||||
content.container.style_context().add_class("popup");
|
content.container.style_context().add_class("popup");
|
||||||
self.window.add(&content.container);
|
self.window.add(&content.container);
|
||||||
|
|
||||||
self.window.show();
|
self.window.show();
|
||||||
self.set_pos(geometry);
|
Self::set_pos(
|
||||||
|
geometry,
|
||||||
|
self.pos.orientation(),
|
||||||
|
&self.monitor,
|
||||||
|
&self.window,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_position(
|
||||||
|
buttons: &[Button],
|
||||||
|
button_id: usize,
|
||||||
|
orientation: Orientation,
|
||||||
|
monitor: &Monitor,
|
||||||
|
window: &ApplicationWindow,
|
||||||
|
) {
|
||||||
|
let button = buttons
|
||||||
|
.iter()
|
||||||
|
.find(|b| b.popup_id() == button_id)
|
||||||
|
.expect("to find valid button");
|
||||||
|
|
||||||
|
let geometry = button.geometry(orientation);
|
||||||
|
Self::set_pos(geometry, orientation, monitor, window);
|
||||||
|
}
|
||||||
|
|
||||||
fn clear_window(&self) {
|
fn clear_window(&self) {
|
||||||
let children = self.window.children();
|
let children = self.window.children();
|
||||||
for child in children {
|
for child in children {
|
||||||
|
@ -166,8 +217,8 @@ impl Popup {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hides the popover
|
/// Hides the popover
|
||||||
pub fn hide(&mut self) {
|
pub fn hide(&self) {
|
||||||
self.current_widget = None;
|
*self.current_widget.borrow_mut() = None;
|
||||||
self.window.hide();
|
self.window.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,22 +228,25 @@ impl Popup {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_widget(&self) -> Option<usize> {
|
pub fn current_widget(&self) -> Option<usize> {
|
||||||
self.current_widget
|
self.current_widget.borrow().map(|w| w.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the popup's X/Y position relative to the left or border of the screen
|
/// Sets the popup's X/Y position relative to the left or border of the screen
|
||||||
/// (depending on orientation).
|
/// (depending on orientation).
|
||||||
fn set_pos(&self, geometry: WidgetGeometry) {
|
fn set_pos(
|
||||||
let orientation = self.pos.get_orientation();
|
geometry: WidgetGeometry,
|
||||||
|
orientation: Orientation,
|
||||||
let mon_workarea = self.monitor.workarea();
|
monitor: &Monitor,
|
||||||
|
window: &ApplicationWindow,
|
||||||
|
) {
|
||||||
|
let mon_workarea = monitor.workarea();
|
||||||
let screen_size = if orientation == Orientation::Horizontal {
|
let screen_size = if orientation == Orientation::Horizontal {
|
||||||
mon_workarea.width()
|
mon_workarea.width()
|
||||||
} else {
|
} else {
|
||||||
mon_workarea.height()
|
mon_workarea.height()
|
||||||
};
|
};
|
||||||
|
|
||||||
let (popup_width, popup_height) = self.window.size();
|
let (popup_width, popup_height) = window.size();
|
||||||
let popup_size = if orientation == Orientation::Horizontal {
|
let popup_size = if orientation == Orientation::Horizontal {
|
||||||
popup_width
|
popup_width
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,6 +271,6 @@ impl Popup {
|
||||||
gtk_layer_shell::Edge::Top
|
gtk_layer_shell::Edge::Top
|
||||||
};
|
};
|
||||||
|
|
||||||
self.window.set_layer_shell_margin(edge, offset as i32);
|
window.set_layer_shell_margin(edge, offset as i32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue