Merge pull request #3247 from benjamin-voisin/menu
Adding the ability to have dropdown menu for modules
This commit is contained in:
commit
9c7a275cd6
|
@ -27,6 +27,10 @@ class ALabel : public AModule {
|
|||
|
||||
bool handleToggle(GdkEventButton *const &e) override;
|
||||
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||
|
||||
std::map<std::string, GtkMenuItem *> submenus_;
|
||||
std::map<std::string, std::string> menuActionsMap_;
|
||||
static void handleGtkMenuEvent(GtkMenuItem *menuitem, gpointer data);
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <glibmm/dispatcher.h>
|
||||
#include <glibmm/markup.h>
|
||||
#include <gtkmm.h>
|
||||
#include <gtkmm/eventbox.h>
|
||||
#include <json/json.h>
|
||||
|
||||
|
@ -44,6 +45,7 @@ class AModule : public IModule {
|
|||
virtual bool handleMouseLeave(GdkEventCrossing *const &ev);
|
||||
virtual bool handleScroll(GdkEventScroll *);
|
||||
virtual bool handleRelease(GdkEventButton *const &ev);
|
||||
GObject *menu_;
|
||||
|
||||
private:
|
||||
bool handleUserEvent(GdkEventButton *const &ev);
|
||||
|
|
|
@ -81,6 +81,19 @@ The *backlight* module displays the current backlight level.
|
|||
default: 1.0 ++
|
||||
The speed at which to change the brightness when scrolling.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLE:
|
||||
|
||||
```
|
||||
|
|
|
@ -109,6 +109,19 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
|||
default: false ++
|
||||
Option to enable battery compatibility if not detected.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{capacity}*: Capacity in percentage
|
||||
|
|
|
@ -129,6 +129,19 @@ Addressed by *bluetooth*
|
|||
typeof: string ++
|
||||
This format is used to define how each connected device should be displayed within the *device_enumerate* format replacement in the tooltip menu.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: Status of the bluetooth device.
|
||||
|
|
|
@ -120,6 +120,18 @@ libcava lives in:
|
|||
:[ string
|
||||
:[ /dev/stdout
|
||||
:[ It's impossible to set it. Waybar sets it to = /dev/stdout for internal needs
|
||||
|[ *menu*
|
||||
:[ string
|
||||
:[
|
||||
:[ Action that popups the menu.
|
||||
|[ *menu-file*
|
||||
:[ string
|
||||
:[
|
||||
:[ Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|
||||
|[ *menu-actions*
|
||||
:[ array
|
||||
:[
|
||||
:[ The actions corresponding to the buttons of the menu.
|
||||
|
||||
Configuration can be provided as:
|
||||
- The only cava configuration file which is provided through *cava_config*. The rest configuration can be skipped
|
||||
|
|
|
@ -84,6 +84,18 @@ $XDG_CONFIG_HOME/waybar/config ++
|
|||
:[ string
|
||||
:[ same as format
|
||||
:[ Tooltip on hover
|
||||
|[ *menu*
|
||||
:[ string
|
||||
:[
|
||||
:[ Action that popups the menu.
|
||||
|[ *menu-file*
|
||||
:[ string
|
||||
:[
|
||||
:[ Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|
||||
|[ *menu-actions*
|
||||
:[ array
|
||||
:[
|
||||
:[ The actions corresponding to the buttons of the menu.
|
||||
|
||||
View all valid format options in *strftime(3)* or have a look https://en.cppreference.com/w/cpp/chrono/duration/formatter
|
||||
|
||||
|
|
|
@ -121,6 +121,19 @@ Addressed by *custom/<name>*
|
|||
default: false ++
|
||||
Option to enable escaping of script output.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# RETURN-TYPE
|
||||
|
||||
When *return-type* is set to *json*, Waybar expects the *exec*-script to output its data in JSON format.
|
||||
|
|
|
@ -93,6 +93,19 @@ Addressed by *disk*
|
|||
typeof: string ++
|
||||
Use with specific_free, specific_used, and specific_total to force calculation to always be in a certain unit. Accepts kB, kiB, MB, Mib, GB, GiB, TB, TiB.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage_used}*: Percentage of disk in use.
|
||||
|
|
|
@ -25,6 +25,19 @@ Addressed by *hyprland/language*
|
|||
typeof: string ++
|
||||
Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "at-translated-set..." is recommended.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
|
|
|
@ -80,6 +80,19 @@ Addressed by *hyprland/submap*
|
|||
default: Default ++
|
||||
Option to set the submap name to display when not in an active submap.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
|
|
|
@ -89,6 +89,19 @@ screensaver, also known as "presentation mode".
|
|||
typeof: string ++
|
||||
This format is used when the inhibit is deactivated.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu. Cannot be "on-click".
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: status (*activated* or *deactivated*)
|
||||
|
|
|
@ -76,6 +76,19 @@ See *systemd-inhibit*(1) for more information.
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu. Cannot be "on-click".
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: status (*activated* or *deactivated*)
|
||||
|
|
|
@ -85,6 +85,19 @@ Addressed by *jack*
|
|||
typeof: string ++
|
||||
Command to execute when the module is updated.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{load}*: The current CPU load estimated by JACK.
|
||||
|
|
|
@ -84,6 +84,19 @@ Addressed by *memory*
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage}*: Percentage of memory in use.
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
waybar-menu(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - menu property
|
||||
|
||||
# OVERVIEW
|
||||
|
||||
|
||||
Some modules support a 'menu', which allows to have a popup menu whan a defined
|
||||
click is done over the module.
|
||||
|
||||
# PROPERTIES
|
||||
|
||||
A module that implements a 'menu' needs 3 properties defined in its config :
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu. The possibles actions are :
|
||||
|
||||
[- *Option*
|
||||
:- *Description*
|
||||
|[ *on-click*
|
||||
:< When you left-click on the module
|
||||
|[ *on-click-release*
|
||||
:< When you release left button on the module
|
||||
|[ *on-double-click*
|
||||
:< When you double left click on the module
|
||||
|[ *on-triple-click*
|
||||
:< When you triple left click on the module
|
||||
|[ *on-click-middle*
|
||||
:< When you middle click on the module using mousewheel
|
||||
|[ *on-click-middle-release*
|
||||
:< When you release mousewheel button on the module
|
||||
|[ *on-double-click-middle*
|
||||
:< When you double middle click on the module
|
||||
|[ *on-triple-click-middle*
|
||||
:< When you triple middle click on the module
|
||||
|[ *on-click-right*
|
||||
:< When you right click on the module using
|
||||
|[ *on-click-right-release*
|
||||
:< When you release right button on the module
|
||||
|[ *on-double-click-right*
|
||||
:< When you double right click on the module
|
||||
|[ *on-triple-click-right*
|
||||
:< When you triple middle click on the module
|
||||
|[ *on-click-backward*
|
||||
:< When you click on the module using mouse backward button
|
||||
|[ *on-click-backward-release*
|
||||
:< When you release mouse backward button on the module
|
||||
|[ *on-double-click-backward*
|
||||
:< When you double click on the module using mouse backward button
|
||||
|[ *on-triple-click-backward*
|
||||
:< When you triple click on the module using mouse backawrd button
|
||||
|[ *on-click-forward*
|
||||
:< When you click on the module using mouse forward button
|
||||
|[ *on-click-forward-release*
|
||||
:< When you release mouse forward button on the module
|
||||
|[ *on-double-click-forward*
|
||||
:< When you double click on the module using mouse forward button
|
||||
|[ *on-triple-click-forward*
|
||||
:< When you triple click on the module using mouse forward button
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*.
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu. The identifiers of
|
||||
each actions needs to exists as an id in the 'menu-file' for it to be linked
|
||||
properly.
|
||||
|
||||
# MENU-FILE
|
||||
|
||||
The menu-file is an `.xml` file representing a GtkBuilder. Documentation for it
|
||||
can be found here : https://docs.gtk.org/gtk4/class.Builder.html
|
||||
|
||||
Here, it needs to have an element of type GtkMenu with id "menu". Eeach actions
|
||||
in *menu-actions* are linked to elements in the *menu-file* file by the id of
|
||||
the elements.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
Module config :
|
||||
```
|
||||
"custom/power": {
|
||||
"format" : "⏻ ",
|
||||
"tooltip": false,
|
||||
"menu": "on-click",
|
||||
"menu-file": "~/.config/waybar/power_menu.xml",
|
||||
"menu-actions": {
|
||||
"shutdown": "shutdown",
|
||||
"reboot": "reboot",
|
||||
"suspend": "systemctl suspend",
|
||||
"hibernate": "systemctl hibernate",
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
~/.config/waybar/power_menu.xml :
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkMenu" id="menu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="suspend">
|
||||
<property name="label">Suspend</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="hibernat">
|
||||
<property name="label">Hibernate</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="shutdown">
|
||||
<property name="label">Shutdown</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="reboot">
|
||||
<property name="label">Reboot</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
```
|
||||
|
||||
# STYLING MENUS
|
||||
|
||||
- *menu*
|
||||
Style for the menu
|
||||
|
||||
- *menuitem*
|
||||
Style for items in the menu
|
||||
|
||||
# EXAMPLE:
|
||||
|
||||
```
|
||||
menu {
|
||||
border-radius: 15px;
|
||||
background: #161320;
|
||||
color: #B5E8E0;
|
||||
}
|
||||
menuitem {
|
||||
border-radius: 15px;
|
||||
}
|
||||
```
|
|
@ -162,6 +162,19 @@ Addressed by *mpd*
|
|||
default: {} ++
|
||||
Icon to show depending on the "single" option (*{ "on": "...", "off": "..." }*)
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
## WHEN PLAYING/PAUSED
|
||||
|
|
|
@ -129,6 +129,19 @@ Addressed by *network*
|
|||
typeof: string ++
|
||||
This format is used when the displayed interface is disabled.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{ifname}*: Name of the network interface.
|
||||
|
|
|
@ -113,6 +113,19 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
|
|||
typeof: array ++
|
||||
Sinks in this list will not be shown as active sink by Waybar. Entries should be the sink's description field.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name.
|
||||
|
|
|
@ -51,6 +51,19 @@ Addressed by *river/layout*
|
|||
typeof: string ++
|
||||
Command to execute when you right-click on the module.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
```
|
||||
|
|
|
@ -65,6 +65,19 @@ Addressed by *river/mode*
|
|||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
|
|
@ -49,6 +49,19 @@ Addressed by *river/window*
|
|||
typeof: string ++
|
||||
Command to execute when you right-click on the module.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
|
|
@ -74,6 +74,19 @@ cursor is over the module, and clicking on the module toggles mute.
|
|||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{volume}*: Volume in percentage.
|
||||
|
|
|
@ -32,6 +32,19 @@ Addressed by *sway/language*
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
|
||||
|
|
|
@ -70,6 +70,19 @@ Addressed by *sway/mode*
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
|
|
@ -36,6 +36,19 @@ Addressed by *sway/scratchpad*
|
|||
default: {app}: {title} ++
|
||||
The format, how information in the tooltip should be displayed.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{icon}*: Icon, as defined in *format-icons*.
|
||||
|
|
|
@ -36,6 +36,19 @@ Addressed by *systemd-failed-units*
|
|||
default: *true* ++
|
||||
Option to hide this module when there is no failing units.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{nr_failed_system}*: Number of failed units from systemwide (PID=1) systemd.
|
||||
|
|
|
@ -111,6 +111,19 @@ Addressed by *temperature*
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{temperatureC}*: Temperature in Celsius.
|
||||
|
|
|
@ -62,6 +62,19 @@ compatible devices in the tooltip.
|
|||
default: true ++
|
||||
Option to disable battery icon.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage}*: The battery capacity in percentage
|
||||
|
|
|
@ -87,6 +87,19 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
|||
default: 100 ++
|
||||
The maximum volume that can be set, in percentage.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{volume}*: Volume in percentage.
|
||||
|
|
|
@ -192,6 +192,7 @@ man_files = files(
|
|||
'man/waybar-idle-inhibitor.5.scd',
|
||||
'man/waybar-image.5.scd',
|
||||
'man/waybar-states.5.scd',
|
||||
'man/waybar-menu.5.scd',
|
||||
'man/waybar-temperature.5.scd',
|
||||
)
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
"battery",
|
||||
"battery#bat2",
|
||||
"clock",
|
||||
"tray"
|
||||
"tray",
|
||||
"custom/power"
|
||||
],
|
||||
// Modules configuration
|
||||
// "sway/workspaces": {
|
||||
|
@ -198,5 +199,17 @@
|
|||
"escape": true,
|
||||
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
|
||||
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
|
||||
},
|
||||
"custom/power": {
|
||||
"format" : "⏻ ",
|
||||
"tooltip": false,
|
||||
"menu": "on-click",
|
||||
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
|
||||
"menu-actions": {
|
||||
"shutdown": "shutdown",
|
||||
"reboot": "reboot",
|
||||
"suspend": "systemctl suspend",
|
||||
"hibernate": "systemctl hibernate"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkMenu" id="menu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="suspend">
|
||||
<property name="label">Suspend</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="hibernate">
|
||||
<property name="label">Hibernate</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="shutdown">
|
||||
<property name="label">Shutdown</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="reboot">
|
||||
<property name="label">Reboot</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <util/command.hpp>
|
||||
|
||||
namespace waybar {
|
||||
|
@ -9,7 +11,9 @@ namespace waybar {
|
|||
ALabel::ALabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||
const std::string& format, uint16_t interval, bool ellipsize, bool enable_click,
|
||||
bool enable_scroll)
|
||||
: AModule(config, name, id, config["format-alt"].isString() || enable_click, enable_scroll),
|
||||
: AModule(config, name, id,
|
||||
config["format-alt"].isString() || config["menu"].isString() || enable_click,
|
||||
enable_scroll),
|
||||
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
||||
interval_(config_["interval"] == "once"
|
||||
? std::chrono::seconds::max()
|
||||
|
@ -51,6 +55,47 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
|||
}
|
||||
}
|
||||
|
||||
// If a GTKMenu is requested in the config
|
||||
if (config_["menu"].isString()) {
|
||||
// Create the GTKMenu widget
|
||||
try {
|
||||
// Check that the file exists
|
||||
std::string menuFile = config_["menu-file"].asString();
|
||||
// Read the menu descriptor file
|
||||
std::ifstream file(menuFile);
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("Failed to open file: " + menuFile);
|
||||
}
|
||||
std::stringstream fileContent;
|
||||
fileContent << file.rdbuf();
|
||||
GtkBuilder* builder = gtk_builder_new();
|
||||
|
||||
// Make the GtkBuilder and check for errors in his parsing
|
||||
if (!gtk_builder_add_from_string(builder, fileContent.str().c_str(), -1, nullptr)) {
|
||||
throw std::runtime_error("Error found in the file " + menuFile);
|
||||
}
|
||||
|
||||
menu_ = gtk_builder_get_object(builder, "menu");
|
||||
if (!menu_) {
|
||||
throw std::runtime_error("Failed to get 'menu' object from GtkBuilder");
|
||||
}
|
||||
submenus_ = std::map<std::string, GtkMenuItem*>();
|
||||
menuActionsMap_ = std::map<std::string, std::string>();
|
||||
|
||||
// Linking actions to the GTKMenu based on
|
||||
for (Json::Value::const_iterator it = config_["menu-actions"].begin();
|
||||
it != config_["menu-actions"].end(); ++it) {
|
||||
std::string key = it.key().asString();
|
||||
submenus_[key] = GTK_MENU_ITEM(gtk_builder_get_object(builder, key.c_str()));
|
||||
menuActionsMap_[key] = it->asString();
|
||||
g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent),
|
||||
(gpointer)menuActionsMap_[key].c_str());
|
||||
}
|
||||
} catch (std::runtime_error& e) {
|
||||
spdlog::warn("Error while creating the menu : {}. Menu popup not activated.", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
if (config_["justify"].isString()) {
|
||||
auto justify_str = config_["justify"].asString();
|
||||
if (justify_str == "left") {
|
||||
|
@ -125,6 +170,10 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
|
|||
return AModule::handleToggle(e);
|
||||
}
|
||||
|
||||
void ALabel::handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data) {
|
||||
waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu");
|
||||
}
|
||||
|
||||
std::string ALabel::getState(uint8_t value, bool lesser) {
|
||||
if (!config_["states"].isObject()) {
|
||||
return "";
|
||||
|
|
|
@ -133,6 +133,16 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
|
|||
|
||||
format = rec->second;
|
||||
}
|
||||
|
||||
// Check that a menu has been configured
|
||||
if (config_["menu"].isString()) {
|
||||
// Check if the event is the one specified for the "menu" option
|
||||
if (rec->second == config_["menu"].asString()) {
|
||||
// Popup the menu
|
||||
gtk_widget_show_all(GTK_WIDGET(menu_));
|
||||
gtk_menu_popup_at_pointer(GTK_MENU(menu_), reinterpret_cast<GdkEvent*>(e));
|
||||
}
|
||||
}
|
||||
// Second call user scripts
|
||||
if (!format.empty()) {
|
||||
if (config_[format].isString())
|
||||
|
|
Loading…
Reference in New Issue