summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/js/simple-bar/widget/Bar.tsx17
-rw-r--r--examples/lua/simple-bar/widget/Bar.lua26
-rw-r--r--examples/vala/simple-bar/widget/Bar.vala21
-rw-r--r--lang/gjs/src/gtk3/astalify.ts5
-rw-r--r--lang/gjs/src/gtk3/jsx-runtime.ts2
-rw-r--r--lang/gjs/src/gtk3/widget.ts9
-rw-r--r--lang/lua/astal/gtk3/widget.lua7
-rw-r--r--lib/tray/meson.build48
-rw-r--r--lib/tray/trayItem.vala111
9 files changed, 105 insertions, 141 deletions
diff --git a/examples/js/simple-bar/widget/Bar.tsx b/examples/js/simple-bar/widget/Bar.tsx
index efc065a..029aca1 100644
--- a/examples/js/simple-bar/widget/Bar.tsx
+++ b/examples/js/simple-bar/widget/Bar.tsx
@@ -13,19 +13,14 @@ function SysTray() {
return <box>
{bind(tray, "items").as(items => items.map(item => {
- if (item.iconThemePath)
- App.add_icons(item.iconThemePath)
-
- const menu = item.create_menu()
-
- return <button
+
+ return <menubutton
tooltipMarkup={bind(item, "tooltipMarkup")}
- onDestroy={() => menu?.destroy()}
- onClickRelease={self => {
- menu?.popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null)
- }}>
+ usePopover={false}
+ actionGroup={bind(item, "action-group").as(ag => { return { prefix: "dbusmenu", actionGroup: ag}})}
+ menuModel={bind(item, "menu-model")} >
<icon gIcon={bind(item, "gicon")} />
- </button>
+ </menubutton>
}))}
</box>
}
diff --git a/examples/lua/simple-bar/widget/Bar.lua b/examples/lua/simple-bar/widget/Bar.lua
index bf230bb..843e292 100644
--- a/examples/lua/simple-bar/widget/Bar.lua
+++ b/examples/lua/simple-bar/widget/Bar.lua
@@ -19,24 +19,16 @@ local function SysTray()
return Widget.Box({
bind(tray, "items"):as(function(items)
return map(items, function(item)
- if item.icon_theme_path ~= nil then
- App:add_icons(item.icon_theme_path)
- end
-
- local menu = item:create_menu()
-
- return Widget.Button({
+ return Widget.MenuButton({
tooltip_markup = bind(item, "tooltip_markup"),
- on_destroy = function()
- if menu ~= nil then
- menu:destroy()
- end
- end,
- on_click_release = function(self)
- if menu ~= nil then
- menu:popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, nil)
- end
- end,
+ use_popover = false,
+ menu_model = bind(item, "menu-model"),
+ action_group = bind(item, "action-group"):as(function(ag)
+ return {
+ prefix = "dbusmenu",
+ action_group = ag
+ }
+ end),
Widget.Icon({
g_icon = bind(item, "gicon"),
}),
diff --git a/examples/vala/simple-bar/widget/Bar.vala b/examples/vala/simple-bar/widget/Bar.vala
index ba4062c..3893ec5 100644
--- a/examples/vala/simple-bar/widget/Bar.vala
+++ b/examples/vala/simple-bar/widget/Bar.vala
@@ -113,22 +113,19 @@ class SysTray : Gtk.Box {
var item = tray.get_item(id);
- var menu = item.create_menu();
- var btn = new Astal.Button();
+ var btn = new Gtk.MenuButton() {
+ use_popover = false
+ };
var icon = new Astal.Icon();
- btn.clicked.connect(() => {
- if (menu != null)
- menu.popup_at_widget(this, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null);
- });
-
- btn.destroy.connect(() => {
- if (menu != null)
- menu.destroy();
- });
-
item.bind_property("tooltip-markup", btn, "tooltip-markup", BindingFlags.SYNC_CREATE);
item.bind_property("gicon", icon, "g-icon", BindingFlags.SYNC_CREATE);
+ item.bind_property("menu-model", btn, "menu-model", BindingFlags.SYNC_CREATE);
+ btn.insert_action_group("dbusmenu", item.action_group);
+ item.notify["action-group"].connect(() => {
+ btn.insert_action_group("dbusmenu", item.action_group);
+ });
+
btn.add(icon);
add(btn);
btn.show_all();
diff --git a/lang/gjs/src/gtk3/astalify.ts b/lang/gjs/src/gtk3/astalify.ts
index 6973805..b758976 100644
--- a/lang/gjs/src/gtk3/astalify.ts
+++ b/lang/gjs/src/gtk3/astalify.ts
@@ -69,6 +69,9 @@ export default function astalify<
get noImplicitDestroy(): boolean { return this.__no_implicit_destroy }
set noImplicitDestroy(value: boolean) { this.__no_implicit_destroy = value }
+ set actionGroup(actionGroup: ActionGroup) { this.insert_action_group(actionGroup.prefix, actionGroup.actionGroup) }
+ set_action_group(actionGroup: ActionGroup) { this.actionGroup = actionGroup }
+
_setChildren(children: Gtk.Widget[]) {
children = children.flat(Infinity).map(ch => ch instanceof Gtk.Widget
? ch
@@ -327,3 +330,5 @@ type Cursor =
| "nwse-resize"
| "zoom-in"
| "zoom-out"
+
+type ActionGroup = { prefix: string, actionGroup: Gtk.ActionGroup }
diff --git a/lang/gjs/src/gtk3/jsx-runtime.ts b/lang/gjs/src/gtk3/jsx-runtime.ts
index 22dc424..10b3bcf 100644
--- a/lang/gjs/src/gtk3/jsx-runtime.ts
+++ b/lang/gjs/src/gtk3/jsx-runtime.ts
@@ -54,6 +54,7 @@ const ctors = {
label: Widget.Label,
levelbar: Widget.LevelBar,
// TODO: listbox
+ menubutton: Widget.MenuButton,
overlay: Widget.Overlay,
revealer: Widget.Revealer,
scrollable: Widget.Scrollable,
@@ -82,6 +83,7 @@ declare global {
label: Widget.LabelProps
levelbar: Widget.LevelBarProps
// TODO: listbox
+ menubutton: Widget.MenuButton,
overlay: Widget.OverlayProps
revealer: Widget.RevealerProps
scrollable: Widget.ScrollableProps
diff --git a/lang/gjs/src/gtk3/widget.ts b/lang/gjs/src/gtk3/widget.ts
index b4e8497..b3c4a4d 100644
--- a/lang/gjs/src/gtk3/widget.ts
+++ b/lang/gjs/src/gtk3/widget.ts
@@ -102,6 +102,15 @@ export class LevelBar extends astalify(Astal.LevelBar) {
// TODO: ListBox
+
+// MenuButton
+export type MenuButtonProps = ConstructProps<MenuButton, Gtk.MenuButton.ConstructorProps>
+export class MenuButton extends astalify(Gtk.MenuButton) {
+ static { GObject.registerClass({ GTypeName: "MenuButton" }, this) }
+ constructor(props?: MenuButtonProps, child?: BindableChild) { super({ child, ...props } as any) }
+}
+
+
// Overlay
Object.defineProperty(Astal.Overlay.prototype, "overlays", {
get() { return this.get_overlays() },
diff --git a/lang/lua/astal/gtk3/widget.lua b/lang/lua/astal/gtk3/widget.lua
index c8857e7..adcb65f 100644
--- a/lang/lua/astal/gtk3/widget.lua
+++ b/lang/lua/astal/gtk3/widget.lua
@@ -19,6 +19,7 @@ local Widget = {
Label = astalify(Gtk.Label),
LevelBar = astalify(Astal.LevelBar),
-- TODO: ListBox
+ MenuButton = astalify(Gtk.MenuButton),
Overlay = astalify(Astal.Overlay),
Revealer = astalify(Gtk.Revealer),
Scrollable = astalify(Astal.Scrollable),
@@ -64,6 +65,12 @@ Gtk.Widget._attribute.click_through = {
set = Astal.widget_set_click_through,
}
+Gtk.Widget._attribute.action_group = {
+ set = function (self, v)
+ self:insert_action_group(v.prefix, v.action_group)
+ end
+}
+
local no_implicit_destroy = {}
Gtk.Widget._attribute.no_implicit_destroy = {
get = function(self)
diff --git a/lib/tray/meson.build b/lib/tray/meson.build
index fbf2f98..139cfb1 100644
--- a/lib/tray/meson.build
+++ b/lib/tray/meson.build
@@ -39,29 +39,9 @@ deps = [
dependency('gio-2.0'),
dependency('json-glib-1.0'),
dependency('gdk-pixbuf-2.0'),
- dependency('gtk+-3.0'),
+ dependency('appmenu-glib-translator')
]
-dbusmenu_cflags = run_command(
- find_program('pkg-config', required: true),
- '--cflags', 'dbusmenu-gtk3-0.4',
- 'gobject-introspection-1.0',
- 'gobject-2.0',
- 'glib-2.0',
- capture: true,
- check: true,
-).stdout().strip()
-
-dbusmenu_libs = run_command(
- find_program('pkg-config', required: true),
- '--libs', 'dbusmenu-gtk3-0.4',
- 'gobject-introspection-1.0',
- 'gobject-2.0',
- 'glib-2.0',
- capture: true,
- check: true,
-).stdout().strip()
-
sources = [config] + files('tray.vala', 'watcher.vala', 'trayItem.vala')
if get_option('lib')
@@ -71,15 +51,13 @@ if get_option('lib')
dependencies: deps,
vala_header: meson.project_name() + '.h',
vala_vapi: meson.project_name() + '-' + api_version + '.vapi',
- vala_args: ['--vapi-comments', '--pkg', 'DbusmenuGtk3-0.4', '--pkg', 'Dbusmenu-0.4'],
+ vala_args: ['--vapi-comments'],
version: meson.project_version(),
- c_args: dbusmenu_cflags.split(' '),
- link_args: dbusmenu_libs.split(' '),
install: true,
install_dir: [true, true, true]
)
- pkgs = ['--pkg', 'DbusmenuGtk3-0.4', '--pkg', 'Dbusmenu-0.4']
+ pkgs = []
foreach dep : deps
pkgs += ['--pkg=' + dep.name()]
endforeach
@@ -120,31 +98,13 @@ if get_option('lib')
requires: deps,
install_dir: get_option('libdir') / 'pkgconfig',
)
- #
- # custom_target(
- # typelib,
- # command: [
- # find_program('g-ir-compiler'),
- # '--output', '@OUTPUT@',
- # '--shared-library', get_option('prefix') / get_option('libdir') / '@PLAINNAME@',
- # meson.current_build_dir() / gir,
- # ],
- # input: lib,
- # output: typelib,
- # depends: lib,
- # install: true,
- # install_dir: get_option('libdir') / 'girepository-1.0',
- # )
-endif
+ endif
if get_option('cli')
executable(
meson.project_name(),
['cli.vala', sources],
dependencies: deps,
- vala_args: ['--pkg', 'DbusmenuGtk3-0.4', '--pkg', 'Dbusmenu-0.4'],
- c_args: dbusmenu_cflags.split(' '),
- link_args: dbusmenu_libs.split(' '),
install: true,
)
endif
diff --git a/lib/tray/trayItem.vala b/lib/tray/trayItem.vala
index db0e6d4..be221bf 100644
--- a/lib/tray/trayItem.vala
+++ b/lib/tray/trayItem.vala
@@ -1,4 +1,3 @@
-using DbusmenuGtk;
namespace AstalTray {
public struct Pixmap {
@@ -169,6 +168,22 @@ public class TrayItem : Object {
/** the id of the item used to uniquely identify the TrayItems by this lib.*/
public string item_id { get; private set; }
+ private DBusMenu.Importer menu_importer;
+
+ public MenuModel menu_model {
+ owned get {
+ if (menu_importer == null) return null;
+ return menu_importer.model;
+ }
+ }
+
+ public ActionGroup action_group {
+ owned get {
+ if (menu_importer == null) return null;
+ return menu_importer.action_group;
+ }
+ }
+
public signal void changed();
public signal void ready();
@@ -197,6 +212,14 @@ public class TrayItem : Object {
}
});
+ if(proxy.Menu != null) {
+ this.menu_importer = new DBusMenu.Importer(proxy.get_name_owner(), proxy.Menu);
+ this.menu_importer.notify["model"].connect(() => {
+ notify_property("menu-model");
+ notify_property("action-group");
+ });
+ }
+
update_gicon();
ready();
@@ -216,18 +239,9 @@ public class TrayItem : Object {
private void update_gicon() {
if(icon_name != null && icon_name != "") {
- if(icon_theme_path != null && icon_theme_path != "") {
-
- Gtk.IconTheme icon_theme = new Gtk.IconTheme();
- string[] paths = {icon_theme_path};
- icon_theme.set_search_path(paths);
-
- int size = icon_theme.get_icon_sizes(icon_name)[0];
- Gtk.IconInfo icon_info = icon_theme.lookup_icon(
- icon_name, size, Gtk.IconLookupFlags.FORCE_SIZE);
-
- if (icon_info != null)
- gicon = new GLib.FileIcon(GLib.File.new_for_path(icon_info.get_filename()));
+ if(icon_theme_path != null && icon_theme_path != "") {
+ gicon = new GLib.FileIcon(GLib.File.new_for_path(
+ find_icon_in_theme(icon_name, icon_theme_path)));
} else {
gicon = new GLib.ThemedIcon(icon_name);
}
@@ -312,16 +326,33 @@ public class TrayItem : Object {
}
}
- /**
- * creates a new Gtk Menu for this item.
- */
- public Gtk.Menu? create_menu() {
- if (proxy.Menu == null)
- return null;
+ private string? find_icon_in_theme(string icon_name, string theme_path){
+ if(icon_name == null || theme_path == null || icon_name == "" || theme_path == "") return null;
+
+ try {
+ Dir dir = Dir.open (theme_path, 0);
+ string? name = null;
+
+ while ((name = dir.read_name ()) != null) {
+ string path = Path.build_filename (theme_path, name);
+
+ if (FileUtils.test (path, FileTest.IS_DIR)) {
+ string? icon = find_icon_in_theme(icon_name, path);
+ if(icon != null) return icon;
+ else continue;
+ }
+
+ int dot_index = name.last_index_of(".");
+ if (dot_index != -1)
+ name = name.substring(0, dot_index);
+ if (name == icon_name) return path;
+
+ }
+ } catch (FileError err) {
+ return null;
+ }
+ return null;
- return new DbusmenuGtk.Menu(
- proxy.get_name_owner(),
- proxy.Menu);
}
private Gdk.Pixbuf? _get_icon_pixbuf() {
@@ -329,41 +360,7 @@ public class TrayItem : Object {
? proxy.AttentionIconPixmap
: proxy.IconPixmap;
-
- string icon_name = proxy.Status == Status.NEEDS_ATTENTION
- ? proxy.AttentionIconName
- : proxy.IconName;
-
- Gdk.Pixbuf pixbuf = null;
-
- if (icon_name != null && proxy.IconThemePath != null)
- pixbuf = load_from_theme(icon_name, proxy.IconThemePath);
-
- if (pixbuf == null)
- pixbuf = pixmap_to_pixbuf(pixmaps);
-
- return pixbuf;
- }
-
- private Gdk.Pixbuf? load_from_theme(string icon_name, string theme_path) {
- if (theme_path == "" || theme_path == null)
- return null;
-
- if (icon_name == "" || icon_name == null)
- return null;
-
- Gtk.IconTheme icon_theme = new Gtk.IconTheme();
- string[] paths = {theme_path};
- icon_theme.set_search_path(paths);
-
- int size = icon_theme.get_icon_sizes(icon_name)[0];
- Gtk.IconInfo icon_info = icon_theme.lookup_icon(
- icon_name, size, Gtk.IconLookupFlags.FORCE_SIZE);
-
- if (icon_info != null)
- return icon_info.load_icon();
-
- return null;
+ return pixmap_to_pixbuf(pixmaps);
}
private Gdk.Pixbuf? pixmap_to_pixbuf(Pixmap[] pixmaps) {