mirror of
https://github.com/JakeStanger/ironbar.git
synced 2024-11-22 05:34:35 +03:00
Merge pull request #780 from JakeStanger/fix/tray-focus
Fix tray focus issues on Sway
This commit is contained in:
commit
e7c56ee09b
@ -8,12 +8,12 @@ Clicking on the widget opens a popup with the time and a calendar.
|
||||
|
||||
> Type: `clock`
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|----------------|----------|------------------------------------|-------------------------------------------------------------------------------------|
|
||||
| `format` | `string` | `%d/%m/%Y %H:%M` | Date/time format string. Pango markup is supported. |
|
||||
| `format_popup` | `string` | `%H:%M:%S` | Date/time format string to display in the popup header. Pango markup is supported. |
|
||||
| `locale` | `string` | `$LC_TIME` or `$LANG` or `'POSIX'` | Locale to use (eg `en_GB`). Defaults to the system language (reading from env var). |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the time on the clock button. |
|
||||
| Name | Type | Default | Description |
|
||||
|----------------|------------------------------------------------------------|------------------------------------|-------------------------------------------------------------------------------------|
|
||||
| `format` | `string` | `%d/%m/%Y %H:%M` | Date/time format string. Pango markup is supported. |
|
||||
| `format_popup` | `string` | `%H:%M:%S` | Date/time format string to display in the popup header. Pango markup is supported. |
|
||||
| `locale` | `string` | `$LC_TIME` or `$LANG` or `'POSIX'` | Locale to use (eg `en_GB`). Defaults to the system language (reading from env var). |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the time on the clock button. |
|
||||
|
||||
> Detail on available tokens can be found here: <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>
|
||||
|
||||
|
@ -6,11 +6,11 @@ Displays a fully interactive icon tray using the KDE `libappindicator` protocol.
|
||||
|
||||
> Type: `tray`
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|----------------------|-----------|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `direction` | `string` | `left_to_right` if bar is horizontal, `top_to_bottom` otherwise | Direction to display the tray items. Possible values: `top_to_bottom`, `bottom_to_top`, `left_to_right`, `right_to_left` |
|
||||
| `icon_size` | `integer` | `16` | Size in pixels to display tray icons as. |
|
||||
| `prefer_theme_icons` | `bool` | `true` | Requests that icons from the theme be used over the item-provided item. Most items only provide one or the other so this will have no effect in most circumstances. |
|
||||
| Name | Type | Default | Description |
|
||||
|----------------------|------------------------------------------------------------|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | Matches bar orientation | The direction in which to pack tray icons. |
|
||||
| `icon_size` | `integer` | `16` | Size in pixels to display tray icons as. |
|
||||
| `prefer_theme_icons` | `bool` | `true` | Requests that icons from the theme be used over the item-provided item. Most items only provide one or the other so this will have no effect in most circumstances. |
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
@ -1,11 +1,13 @@
|
||||
use glib::Propagation;
|
||||
use gtk::gdk::Gravity;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Image, Label, MenuItem};
|
||||
use gtk::{EventBox, Image, Label, MenuItem};
|
||||
use system_tray::item::{IconPixmap, StatusNotifierItem, Tooltip};
|
||||
|
||||
/// Main tray icon to show on the bar
|
||||
pub(crate) struct TrayMenu {
|
||||
pub event_box: EventBox,
|
||||
pub widget: MenuItem,
|
||||
menu_widget: Option<system_tray::gtk_menu::Menu>,
|
||||
image_widget: Option<Image>,
|
||||
label_widget: Option<Label>,
|
||||
|
||||
@ -17,12 +19,17 @@ pub(crate) struct TrayMenu {
|
||||
|
||||
impl TrayMenu {
|
||||
pub fn new(item: StatusNotifierItem) -> Self {
|
||||
let event_box = EventBox::new();
|
||||
|
||||
let widget = MenuItem::new();
|
||||
widget.style_context().add_class("item");
|
||||
event_box.add(&widget);
|
||||
|
||||
event_box.show_all();
|
||||
|
||||
Self {
|
||||
event_box,
|
||||
widget,
|
||||
menu_widget: None,
|
||||
image_widget: None,
|
||||
label_widget: None,
|
||||
title: item.title,
|
||||
@ -99,7 +106,10 @@ impl TrayMenu {
|
||||
}
|
||||
|
||||
pub fn set_menu_widget(&mut self, menu: system_tray::gtk_menu::Menu) {
|
||||
self.widget.set_submenu(Some(&menu));
|
||||
self.menu_widget = Some(menu);
|
||||
self.event_box
|
||||
.connect_button_press_event(move |event_box, _event| {
|
||||
menu.popup_at_widget(event_box, Gravity::North, Gravity::South, None);
|
||||
Propagation::Proceed
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ mod icon;
|
||||
mod interface;
|
||||
|
||||
use crate::clients::tray;
|
||||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, ModuleOrientation};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, lock, module_impl, send_async, spawn};
|
||||
use color_eyre::{Report, Result};
|
||||
use gtk::{prelude::*, PackDirection};
|
||||
use gtk::{IconTheme, MenuBar};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{IconTheme, Orientation};
|
||||
use interface::TrayMenu;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
@ -32,15 +32,13 @@ pub struct TrayModule {
|
||||
#[serde(default = "default_icon_size")]
|
||||
icon_size: u32,
|
||||
|
||||
/// Direction to display the tray items.
|
||||
/// The direction in which to pack tray icons.
|
||||
///
|
||||
/// **Valid options**: `top_to_bottom`, `bottom_to_top`, `left_to_right`, `right_to_left`
|
||||
/// **Valid options**: `horizontal`, `vertical`
|
||||
/// <br>
|
||||
/// **Default**: `left_to_right` if bar is horizontal, `top_to_bottom` if bar is vertical
|
||||
#[serde(default, deserialize_with = "deserialize_pack_direction")]
|
||||
#[cfg_attr(feature = "schema", schemars(schema_with = "schema_pack_direction"))]
|
||||
direction: Option<PackDirection>,
|
||||
|
||||
/// **Default**: `horizontal` for horizontal bars, `vertical` for vertical bars
|
||||
#[serde(default)]
|
||||
direction: Option<ModuleOrientation>,
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
@ -50,36 +48,7 @@ const fn default_icon_size() -> u32 {
|
||||
16
|
||||
}
|
||||
|
||||
fn deserialize_pack_direction<'de, D>(deserializer: D) -> Result<Option<PackDirection>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let value = Option::<String>::deserialize(deserializer)?;
|
||||
value
|
||||
.map(|v| match v.as_str() {
|
||||
"left_to_right" => Ok(PackDirection::Ltr),
|
||||
"right_to_left" => Ok(PackDirection::Rtl),
|
||||
"top_to_bottom" => Ok(PackDirection::Ttb),
|
||||
"bottom_to_top" => Ok(PackDirection::Btt),
|
||||
_ => Err(serde::de::Error::custom("invalid value for direction")),
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
#[cfg(feature = "schema")]
|
||||
fn schema_pack_direction(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
use schemars::JsonSchema;
|
||||
let mut schema: schemars::schema::SchemaObject = <String>::json_schema(gen).into();
|
||||
schema.enum_values = Some(vec![
|
||||
"top_to_bottom".into(),
|
||||
"bottom_to_top".into(),
|
||||
"left_to_right".into(),
|
||||
"right_to_left".into(),
|
||||
]);
|
||||
schema.into()
|
||||
}
|
||||
|
||||
impl Module<MenuBar> for TrayModule {
|
||||
impl Module<gtk::Box> for TrayModule {
|
||||
type SendMessage = Event;
|
||||
type ReceiveMessage = ActivateRequest;
|
||||
|
||||
@ -137,19 +106,17 @@ impl Module<MenuBar> for TrayModule {
|
||||
self,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<MenuBar>> {
|
||||
let container = MenuBar::new();
|
||||
) -> Result<ModuleParts<gtk::Box>> {
|
||||
let orientation = self
|
||||
.direction
|
||||
.map(Orientation::from)
|
||||
.unwrap_or(info.bar_position.orientation());
|
||||
|
||||
let direction = self.direction.unwrap_or(
|
||||
if info.bar_position.orientation() == gtk::Orientation::Vertical {
|
||||
PackDirection::Ttb
|
||||
} else {
|
||||
PackDirection::Ltr
|
||||
},
|
||||
);
|
||||
|
||||
container.set_pack_direction(direction);
|
||||
container.set_child_pack_direction(direction);
|
||||
// We use a `Box` here instead of the (supposedly correct) `MenuBar`
|
||||
// as the latter has issues on Sway with menus focus-stealing from the bar.
|
||||
//
|
||||
// Each widget is wrapped in an EventBox, copying what Waybar does here.
|
||||
let container = gtk::Box::new(orientation, 10);
|
||||
|
||||
{
|
||||
let container = container.clone();
|
||||
@ -173,7 +140,7 @@ impl Module<MenuBar> for TrayModule {
|
||||
/// getting the diff since the previous update and applying it to the menu.
|
||||
fn on_update(
|
||||
update: Event,
|
||||
container: &MenuBar,
|
||||
container: >k::Box,
|
||||
menus: &mut HashMap<Box<str>, TrayMenu>,
|
||||
icon_theme: &IconTheme,
|
||||
icon_size: u32,
|
||||
@ -184,7 +151,7 @@ fn on_update(
|
||||
debug!("Received new tray item at '{address}': {item:?}");
|
||||
|
||||
let mut menu_item = TrayMenu::new(*item);
|
||||
container.add(&menu_item.widget);
|
||||
container.pack_start(&menu_item.event_box, true, true, 0);
|
||||
|
||||
if let Ok(image) = icon::get_image(&menu_item, icon_theme, icon_size, prefer_icons) {
|
||||
menu_item.set_image(&image);
|
||||
|
Loading…
Reference in New Issue
Block a user