mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
V3 alpha linux dbus (#2996)
* [v3 linux/systray] dbus generation * [v3 linux] systemtray dbus implementation * [v3] add 'id' for MenuSeparator This is needed in order to have a unique value for all menuItem(s) such that the Linux implementation doesn't have to generate new identifiers. Allowing the reuse keeps a 1-1 mapping in place without any extra effort. * [v3 example/systray] add radio group to example * [v3 linux] stub out ExportStatusNotifierItem callbacks Can only seem to get the `SecondaryActivate` to fire when doing a 3-finger click! I was expecting a right-click interaction to trigger it.
This commit is contained in:
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
@@ -71,6 +72,19 @@ func main() {
|
||||
println("Click me!")
|
||||
ctx.ClickedMenuItem().SetLabel("Disabled!").SetEnabled(false)
|
||||
})
|
||||
myMenu.AddSeparator()
|
||||
// Callbacks can be shared. This is useful for radio groups
|
||||
radioCallback := func(ctx *application.Context) {
|
||||
menuItem := ctx.ClickedMenuItem()
|
||||
menuItem.SetLabel(menuItem.Label() + "!")
|
||||
fmt.Println("radioCallback: ")
|
||||
}
|
||||
|
||||
// Radio groups are created implicitly by placing radio items next to each other in a menu
|
||||
myMenu.AddRadio("Radio 1", true).OnClick(radioCallback)
|
||||
myMenu.AddRadio("Radio 2", false).OnClick(radioCallback)
|
||||
myMenu.AddRadio("Radio 3", false).OnClick(radioCallback)
|
||||
|
||||
myMenu.AddSeparator()
|
||||
myMenu.Add("Quit").OnClick(func(ctx *application.Context) {
|
||||
app.Quit()
|
||||
|
||||
@@ -8,6 +8,7 @@ require (
|
||||
github.com/go-git/go-git/v5 v5.3.0
|
||||
github.com/go-ole/go-ole v1.2.6
|
||||
github.com/go-task/task/v3 v3.31.0
|
||||
github.com/godbus/dbus/v5 v5.1.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/pat v1.0.1
|
||||
|
||||
@@ -119,6 +119,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ
|
||||
github.com/go-task/task/v3 v3.31.0 h1:o6iyj9gPJXxvxPi/u/l8e025PmM2BqKgtLNPS2i7hV4=
|
||||
github.com/go-task/task/v3 v3.31.0/go.mod h1:/CPDAu9nS3+soqY/e1tTrSo/zxk76lnljEV9aBTeKrg=
|
||||
github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<node name="/" xmlns:dox="http://www.canonical.com/dbus/dox.dtd">
|
||||
<interface name="com.canonical.dbusmenu">
|
||||
<!-- Properties -->
|
||||
<property name="Version" type="u" access="read"/>
|
||||
<property name="TextDirection" type="s" access="read"/>
|
||||
<property name="Status" type="s" access="read"/>
|
||||
<property name="IconThemePath" type="as" access="read"/>
|
||||
<!-- Functions -->
|
||||
<method name="GetLayout">
|
||||
<arg type="i" name="parentId" direction="in"/>
|
||||
<arg type="i" name="recursionDepth" direction="in"/>
|
||||
<arg type="as" name="propertyNames" direction="in"/>
|
||||
<arg type="u" name="revision" direction="out"/>
|
||||
<arg type="(ia{sv}av)" name="layout" direction="out"/>
|
||||
</method>
|
||||
<method name="GetGroupProperties">
|
||||
<arg type="ai" name="ids" direction="in"/>
|
||||
<arg type="as" name="propertyNames" direction="in"/>
|
||||
<arg type="a(ia{sv})" name="properties" direction="out"/>
|
||||
</method>
|
||||
<method name="GetProperty">
|
||||
<arg type="i" name="id" direction="in"/>
|
||||
<arg type="s" name="name" direction="in"/>
|
||||
<arg type="v" name="value" direction="out"/>
|
||||
</method>
|
||||
<method name="Event">
|
||||
<arg type="i" name="id" direction="in"/>
|
||||
<arg type="s" name="eventId" direction="in"/>
|
||||
<arg type="v" name="data" direction="in"/>
|
||||
<arg type="u" name="timestamp" direction="in"/>
|
||||
</method>
|
||||
<method name="EventGroup">
|
||||
<arg type="a(isvu)" name="events" direction="in"/>
|
||||
<arg type="ai" name="idErrors" direction="out"/>
|
||||
</method>
|
||||
<method name="AboutToShow">
|
||||
<arg type="i" name="id" direction="in"/>
|
||||
<arg type="b" name="needUpdate" direction="out"/>
|
||||
</method>
|
||||
<method name="AboutToShowGroup">
|
||||
<arg type="ai" name="ids" direction="in"/>
|
||||
<arg type="ai" name="updatesNeeded" direction="out"/>
|
||||
<arg type="ai" name="idErrors" direction="out"/>
|
||||
</method>
|
||||
<!-- Signals -->
|
||||
<signal name="ItemsPropertiesUpdated">
|
||||
<arg type="a(ia{sv})" name="updatedProps" direction="out"/>
|
||||
<arg type="a(ias)" name="removedProps" direction="out"/>
|
||||
</signal>
|
||||
<signal name="LayoutUpdated">
|
||||
<arg type="u" name="revision" direction="out"/>
|
||||
<arg type="i" name="parent" direction="out"/>
|
||||
</signal>
|
||||
<signal name="ItemActivationRequested">
|
||||
<arg type="i" name="id" direction="out"/>
|
||||
<arg type="u" name="timestamp" direction="out"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -0,0 +1,5 @@
|
||||
//Note that you need to have github.com/knightpp/dbus-codegen-go installed from "custom" branch
|
||||
|
||||
//go:generate dbus-codegen-go -prefix org.kde -package notifier -output internal/generated/notifier/status_notifier_item.go internal/StatusNotifierItem.xml
|
||||
//go:generate dbus-codegen-go -prefix com.canonical -package menu -output internal/generated/menu/dbus_menu.go internal/DbusMenu.xml
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<node name="/StatusNotifierItem">
|
||||
<!-- Based on:
|
||||
https://invent.kde.org/frameworks/knotifications/-/blob/master/src/org.kde.StatusNotifierItem.xml
|
||||
-->
|
||||
<interface name="org.kde.StatusNotifierItem">
|
||||
<property name="Category" type="s" access="read"/>
|
||||
<property name="Id" type="s" access="read"/>
|
||||
<property name="Title" type="s" access="read"/>
|
||||
<property name="Status" type="s" access="read"/>
|
||||
<property name="WindowId" type="i" access="read"/>
|
||||
<!-- An additional path to add to the theme search path to find the icons specified above. -->
|
||||
<property name="IconThemePath" type="s" access="read"/>
|
||||
<property name="Menu" type="o" access="read"/>
|
||||
<property name="ItemIsMenu" type="b" access="read"/>
|
||||
<!-- main icon -->
|
||||
<!-- names are preferred over pixmaps -->
|
||||
<property name="IconName" type="s" access="read"/>
|
||||
<!-- struct containing width, height and image data -->
|
||||
<property name="IconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="KDbusImageVector"/>
|
||||
</property>
|
||||
<property name="OverlayIconName" type="s" access="read"/>
|
||||
<property name="OverlayIconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="KDbusImageVector"/>
|
||||
</property>
|
||||
<!-- Requesting attention icon -->
|
||||
<property name="AttentionIconName" type="s" access="read"/>
|
||||
<!-- same definition as image -->
|
||||
<property name="AttentionIconPixmap" type="a(iiay)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="KDbusImageVector"/>
|
||||
</property>
|
||||
<property name="AttentionMovieName" type="s" access="read"/>
|
||||
<!-- tooltip data -->
|
||||
<!-- (iiay) is an image -->
|
||||
<property name="ToolTip" type="(sa(iiay)ss)" access="read">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="KDbusToolTipStruct"/>
|
||||
</property>
|
||||
<!-- interaction: the systemtray wants the application to do something -->
|
||||
<method name="ContextMenu">
|
||||
<!-- we're passing the coordinates of the icon, so the app knows where to put the popup window -->
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="Activate">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="SecondaryActivate">
|
||||
<arg name="x" type="i" direction="in"/>
|
||||
<arg name="y" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="Scroll">
|
||||
<arg name="delta" type="i" direction="in"/>
|
||||
<arg name="orientation" type="s" direction="in"/>
|
||||
</method>
|
||||
<!-- Signals: the client wants to change something in the status -->
|
||||
<signal name="NewTitle"> </signal>
|
||||
<signal name="NewIcon"> </signal>
|
||||
<signal name="NewAttentionIcon"> </signal>
|
||||
<signal name="NewOverlayIcon"> </signal>
|
||||
<!-- We disable this as we don't support tooltip, so no need to go through it
|
||||
<signal name="NewToolTip">
|
||||
</signal>
|
||||
-->
|
||||
<signal name="NewStatus">
|
||||
<arg name="status" type="s"/>
|
||||
</signal>
|
||||
<!-- The following items are not supported by specs, but widely used -->
|
||||
<signal name="NewIconThemePath">
|
||||
<arg type="s" name="icon_theme_path" direction="out"/>
|
||||
</signal>
|
||||
<signal name="NewMenu"/>
|
||||
<!-- ayatana labels -->
|
||||
<!-- These are commented out because GDBusProxy would otherwise require them,
|
||||
but they are not available for KDE indicators
|
||||
-->
|
||||
<!-- <signal name="XAyatanaNewLabel">
|
||||
<arg type="s" name="label" direction="out" />
|
||||
<arg type="s" name="guide" direction="out" />
|
||||
</signal>
|
||||
<property name="XAyatanaLabel" type="s" access="read" />
|
||||
<property name="XAyatanaLabelGuide" type="s" access="read" /> -->
|
||||
</interface>
|
||||
</node>
|
||||
@@ -0,0 +1,4 @@
|
||||
package dbus
|
||||
|
||||
//go:generate dbus-codegen-go -prefix org.kde -package notifier -output notifier/status_notifier_item.go StatusNotifierItem.xml
|
||||
//go:generate dbus-codegen-go -prefix com.canonical -package menu -output menu/dbus_menu.go DbusMenu.xml
|
||||
@@ -0,0 +1,2 @@
|
||||
dbus-codegen-go -prefix com.canonical -package menu -output dbus_menu.go DbusMenu.xml
|
||||
dbus-codegen-go -prefix org.kde -package notifier -output status_notifier_item.go StatusNotifierItem.xml
|
||||
@@ -0,0 +1,483 @@
|
||||
// Code generated by dbus-codegen-go DO NOT EDIT.
|
||||
package menu
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/godbus/dbus/v5"
|
||||
"github.com/godbus/dbus/v5/introspect"
|
||||
)
|
||||
|
||||
var (
|
||||
// Introspection for com.canonical.dbusmenu
|
||||
IntrospectDataDbusmenu = introspect.Interface{
|
||||
Name: "com.canonical.dbusmenu",
|
||||
Methods: []introspect.Method{{Name: "GetLayout", Args: []introspect.Arg{
|
||||
{Name: "parentId", Type: "i", Direction: "in"},
|
||||
{Name: "recursionDepth", Type: "i", Direction: "in"},
|
||||
{Name: "propertyNames", Type: "as", Direction: "in"},
|
||||
{Name: "revision", Type: "u", Direction: "out"},
|
||||
{Name: "layout", Type: "(ia{sv}av)", Direction: "out"},
|
||||
}},
|
||||
{Name: "GetGroupProperties", Args: []introspect.Arg{
|
||||
{Name: "ids", Type: "ai", Direction: "in"},
|
||||
{Name: "propertyNames", Type: "as", Direction: "in"},
|
||||
{Name: "properties", Type: "a(ia{sv})", Direction: "out"},
|
||||
}},
|
||||
{Name: "GetProperty", Args: []introspect.Arg{
|
||||
{Name: "id", Type: "i", Direction: "in"},
|
||||
{Name: "name", Type: "s", Direction: "in"},
|
||||
{Name: "value", Type: "v", Direction: "out"},
|
||||
}},
|
||||
{Name: "Event", Args: []introspect.Arg{
|
||||
{Name: "id", Type: "i", Direction: "in"},
|
||||
{Name: "eventId", Type: "s", Direction: "in"},
|
||||
{Name: "data", Type: "v", Direction: "in"},
|
||||
{Name: "timestamp", Type: "u", Direction: "in"},
|
||||
}},
|
||||
{Name: "EventGroup", Args: []introspect.Arg{
|
||||
{Name: "events", Type: "a(isvu)", Direction: "in"},
|
||||
{Name: "idErrors", Type: "ai", Direction: "out"},
|
||||
}},
|
||||
{Name: "AboutToShow", Args: []introspect.Arg{
|
||||
{Name: "id", Type: "i", Direction: "in"},
|
||||
{Name: "needUpdate", Type: "b", Direction: "out"},
|
||||
}},
|
||||
{Name: "AboutToShowGroup", Args: []introspect.Arg{
|
||||
{Name: "ids", Type: "ai", Direction: "in"},
|
||||
{Name: "updatesNeeded", Type: "ai", Direction: "out"},
|
||||
{Name: "idErrors", Type: "ai", Direction: "out"},
|
||||
}},
|
||||
},
|
||||
Signals: []introspect.Signal{{Name: "ItemsPropertiesUpdated", Args: []introspect.Arg{
|
||||
{Name: "updatedProps", Type: "a(ia{sv})", Direction: "out"},
|
||||
{Name: "removedProps", Type: "a(ias)", Direction: "out"},
|
||||
}},
|
||||
{Name: "LayoutUpdated", Args: []introspect.Arg{
|
||||
{Name: "revision", Type: "u", Direction: "out"},
|
||||
{Name: "parent", Type: "i", Direction: "out"},
|
||||
}},
|
||||
{Name: "ItemActivationRequested", Args: []introspect.Arg{
|
||||
{Name: "id", Type: "i", Direction: "out"},
|
||||
{Name: "timestamp", Type: "u", Direction: "out"},
|
||||
}},
|
||||
},
|
||||
Properties: []introspect.Property{{Name: "Version", Type: "u", Access: "read"},
|
||||
{Name: "TextDirection", Type: "s", Access: "read"},
|
||||
{Name: "Status", Type: "s", Access: "read"},
|
||||
{Name: "IconThemePath", Type: "as", Access: "read"},
|
||||
},
|
||||
Annotations: []introspect.Annotation{},
|
||||
}
|
||||
)
|
||||
|
||||
// Signal is a common interface for all signals.
|
||||
type Signal interface {
|
||||
Name() string
|
||||
Interface() string
|
||||
Sender() string
|
||||
|
||||
path() dbus.ObjectPath
|
||||
values() []interface{}
|
||||
}
|
||||
|
||||
// Emit sends the given signal to the bus.
|
||||
func Emit(conn *dbus.Conn, s Signal) error {
|
||||
return conn.Emit(s.path(), s.Interface()+"."+s.Name(), s.values()...)
|
||||
}
|
||||
|
||||
// ErrUnknownSignal is returned by LookupSignal when a signal cannot be resolved.
|
||||
var ErrUnknownSignal = errors.New("unknown signal")
|
||||
|
||||
// LookupSignal converts the given raw D-Bus signal with variable body
|
||||
// into one with typed structured body or returns ErrUnknownSignal error.
|
||||
func LookupSignal(signal *dbus.Signal) (Signal, error) {
|
||||
switch signal.Name {
|
||||
case InterfaceDbusmenu + "." + "ItemsPropertiesUpdated":
|
||||
v0, ok := signal.Body[0].([]struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prop .UpdatedProps is %T, not []struct {V0 int32;V1 map[string]dbus.Variant}", signal.Body[0])
|
||||
}
|
||||
v1, ok := signal.Body[1].([]struct {
|
||||
V0 int32
|
||||
V1 []string
|
||||
})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prop .RemovedProps is %T, not []struct {V0 int32;V1 []string}", signal.Body[1])
|
||||
}
|
||||
return &Dbusmenu_ItemsPropertiesUpdatedSignal{
|
||||
sender: signal.Sender,
|
||||
Path: signal.Path,
|
||||
Body: &Dbusmenu_ItemsPropertiesUpdatedSignalBody{
|
||||
UpdatedProps: v0,
|
||||
RemovedProps: v1,
|
||||
},
|
||||
}, nil
|
||||
case InterfaceDbusmenu + "." + "LayoutUpdated":
|
||||
v0, ok := signal.Body[0].(uint32)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prop .Revision is %T, not uint32", signal.Body[0])
|
||||
}
|
||||
v1, ok := signal.Body[1].(int32)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prop .Parent is %T, not int32", signal.Body[1])
|
||||
}
|
||||
return &Dbusmenu_LayoutUpdatedSignal{
|
||||
sender: signal.Sender,
|
||||
Path: signal.Path,
|
||||
Body: &Dbusmenu_LayoutUpdatedSignalBody{
|
||||
Revision: v0,
|
||||
Parent: v1,
|
||||
},
|
||||
}, nil
|
||||
case InterfaceDbusmenu + "." + "ItemActivationRequested":
|
||||
v0, ok := signal.Body[0].(int32)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prop .Id is %T, not int32", signal.Body[0])
|
||||
}
|
||||
v1, ok := signal.Body[1].(uint32)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prop .Timestamp is %T, not uint32", signal.Body[1])
|
||||
}
|
||||
return &Dbusmenu_ItemActivationRequestedSignal{
|
||||
sender: signal.Sender,
|
||||
Path: signal.Path,
|
||||
Body: &Dbusmenu_ItemActivationRequestedSignalBody{
|
||||
Id: v0,
|
||||
Timestamp: v1,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
return nil, ErrUnknownSignal
|
||||
}
|
||||
}
|
||||
|
||||
// AddMatchSignal registers a match rule for the given signal,
|
||||
// opts are appended to the automatically generated signal's rules.
|
||||
func AddMatchSignal(conn *dbus.Conn, s Signal, opts ...dbus.MatchOption) error {
|
||||
return conn.AddMatchSignal(append([]dbus.MatchOption{
|
||||
dbus.WithMatchInterface(s.Interface()),
|
||||
dbus.WithMatchMember(s.Name()),
|
||||
}, opts...)...)
|
||||
}
|
||||
|
||||
// RemoveMatchSignal unregisters the previously registered subscription.
|
||||
func RemoveMatchSignal(conn *dbus.Conn, s Signal, opts ...dbus.MatchOption) error {
|
||||
return conn.RemoveMatchSignal(append([]dbus.MatchOption{
|
||||
dbus.WithMatchInterface(s.Interface()),
|
||||
dbus.WithMatchMember(s.Name()),
|
||||
}, opts...)...)
|
||||
}
|
||||
|
||||
// Interface name constants.
|
||||
const (
|
||||
InterfaceDbusmenu = "com.canonical.dbusmenu"
|
||||
)
|
||||
|
||||
// Dbusmenuer is com.canonical.dbusmenu interface.
|
||||
type Dbusmenuer interface {
|
||||
// GetLayout is com.canonical.dbusmenu.GetLayout method.
|
||||
GetLayout(parentId int32, recursionDepth int32, propertyNames []string) (revision uint32, layout struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
V2 []dbus.Variant
|
||||
}, err *dbus.Error)
|
||||
// GetGroupProperties is com.canonical.dbusmenu.GetGroupProperties method.
|
||||
GetGroupProperties(ids []int32, propertyNames []string) (properties []struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
}, err *dbus.Error)
|
||||
// GetProperty is com.canonical.dbusmenu.GetProperty method.
|
||||
GetProperty(id int32, name string) (value dbus.Variant, err *dbus.Error)
|
||||
// Event is com.canonical.dbusmenu.Event method.
|
||||
Event(id int32, eventId string, data dbus.Variant, timestamp uint32) (err *dbus.Error)
|
||||
// EventGroup is com.canonical.dbusmenu.EventGroup method.
|
||||
EventGroup(events []struct {
|
||||
V0 int32
|
||||
V1 string
|
||||
V2 dbus.Variant
|
||||
V3 uint32
|
||||
}) (idErrors []int32, err *dbus.Error)
|
||||
// AboutToShow is com.canonical.dbusmenu.AboutToShow method.
|
||||
AboutToShow(id int32) (needUpdate bool, err *dbus.Error)
|
||||
// AboutToShowGroup is com.canonical.dbusmenu.AboutToShowGroup method.
|
||||
AboutToShowGroup(ids []int32) (updatesNeeded []int32, idErrors []int32, err *dbus.Error)
|
||||
}
|
||||
|
||||
// ExportDbusmenu exports the given object that implements com.canonical.dbusmenu on the bus.
|
||||
func ExportDbusmenu(conn *dbus.Conn, path dbus.ObjectPath, v Dbusmenuer) error {
|
||||
return conn.ExportSubtreeMethodTable(map[string]interface{}{
|
||||
"GetLayout": v.GetLayout,
|
||||
"GetGroupProperties": v.GetGroupProperties,
|
||||
"GetProperty": v.GetProperty,
|
||||
"Event": v.Event,
|
||||
"EventGroup": v.EventGroup,
|
||||
"AboutToShow": v.AboutToShow,
|
||||
"AboutToShowGroup": v.AboutToShowGroup,
|
||||
}, path, InterfaceDbusmenu)
|
||||
}
|
||||
|
||||
// UnexportDbusmenu unexports com.canonical.dbusmenu interface on the named path.
|
||||
func UnexportDbusmenu(conn *dbus.Conn, path dbus.ObjectPath) error {
|
||||
return conn.Export(nil, path, InterfaceDbusmenu)
|
||||
}
|
||||
|
||||
// UnimplementedDbusmenu can be embedded to have forward compatible server implementations.
|
||||
type UnimplementedDbusmenu struct{}
|
||||
|
||||
func (*UnimplementedDbusmenu) iface() string {
|
||||
return InterfaceDbusmenu
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) GetLayout(parentId int32, recursionDepth int32, propertyNames []string) (revision uint32, layout struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
V2 []dbus.Variant
|
||||
}, err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) GetGroupProperties(ids []int32, propertyNames []string) (properties []struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
}, err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) GetProperty(id int32, name string) (value dbus.Variant, err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) Event(id int32, eventId string, data dbus.Variant, timestamp uint32) (err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) EventGroup(events []struct {
|
||||
V0 int32
|
||||
V1 string
|
||||
V2 dbus.Variant
|
||||
V3 uint32
|
||||
}) (idErrors []int32, err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) AboutToShow(id int32) (needUpdate bool, err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
func (*UnimplementedDbusmenu) AboutToShowGroup(ids []int32) (updatesNeeded []int32, idErrors []int32, err *dbus.Error) {
|
||||
err = &dbus.ErrMsgUnknownMethod
|
||||
return
|
||||
}
|
||||
|
||||
// NewDbusmenu creates and allocates com.canonical.dbusmenu.
|
||||
func NewDbusmenu(object dbus.BusObject) *Dbusmenu {
|
||||
return &Dbusmenu{object}
|
||||
}
|
||||
|
||||
// Dbusmenu implements com.canonical.dbusmenu D-Bus interface.
|
||||
type Dbusmenu struct {
|
||||
object dbus.BusObject
|
||||
}
|
||||
|
||||
// GetLayout calls com.canonical.dbusmenu.GetLayout method.
|
||||
func (o *Dbusmenu) GetLayout(ctx context.Context, parentId int32, recursionDepth int32, propertyNames []string) (revision uint32, layout struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
V2 []dbus.Variant
|
||||
}, err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".GetLayout", 0, parentId, recursionDepth, propertyNames).Store(&revision, &layout)
|
||||
return
|
||||
}
|
||||
|
||||
// GetGroupProperties calls com.canonical.dbusmenu.GetGroupProperties method.
|
||||
func (o *Dbusmenu) GetGroupProperties(ctx context.Context, ids []int32, propertyNames []string) (properties []struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
}, err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".GetGroupProperties", 0, ids, propertyNames).Store(&properties)
|
||||
return
|
||||
}
|
||||
|
||||
// GetProperty calls com.canonical.dbusmenu.GetProperty method.
|
||||
func (o *Dbusmenu) GetProperty(ctx context.Context, id int32, name string) (value dbus.Variant, err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".GetProperty", 0, id, name).Store(&value)
|
||||
return
|
||||
}
|
||||
|
||||
// Event calls com.canonical.dbusmenu.Event method.
|
||||
func (o *Dbusmenu) Event(ctx context.Context, id int32, eventId string, data dbus.Variant, timestamp uint32) (err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".Event", 0, id, eventId, data, timestamp).Store()
|
||||
return
|
||||
}
|
||||
|
||||
// EventGroup calls com.canonical.dbusmenu.EventGroup method.
|
||||
func (o *Dbusmenu) EventGroup(ctx context.Context, events []struct {
|
||||
V0 int32
|
||||
V1 string
|
||||
V2 dbus.Variant
|
||||
V3 uint32
|
||||
}) (idErrors []int32, err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".EventGroup", 0, events).Store(&idErrors)
|
||||
return
|
||||
}
|
||||
|
||||
// AboutToShow calls com.canonical.dbusmenu.AboutToShow method.
|
||||
func (o *Dbusmenu) AboutToShow(ctx context.Context, id int32) (needUpdate bool, err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".AboutToShow", 0, id).Store(&needUpdate)
|
||||
return
|
||||
}
|
||||
|
||||
// AboutToShowGroup calls com.canonical.dbusmenu.AboutToShowGroup method.
|
||||
func (o *Dbusmenu) AboutToShowGroup(ctx context.Context, ids []int32) (updatesNeeded []int32, idErrors []int32, err error) {
|
||||
err = o.object.CallWithContext(ctx, InterfaceDbusmenu+".AboutToShowGroup", 0, ids).Store(&updatesNeeded, &idErrors)
|
||||
return
|
||||
}
|
||||
|
||||
// GetVersion gets com.canonical.dbusmenu.Version property.
|
||||
func (o *Dbusmenu) GetVersion(ctx context.Context) (version uint32, err error) {
|
||||
err = o.object.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, InterfaceDbusmenu, "Version").Store(&version)
|
||||
return
|
||||
}
|
||||
|
||||
// GetTextDirection gets com.canonical.dbusmenu.TextDirection property.
|
||||
func (o *Dbusmenu) GetTextDirection(ctx context.Context) (textDirection string, err error) {
|
||||
err = o.object.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, InterfaceDbusmenu, "TextDirection").Store(&textDirection)
|
||||
return
|
||||
}
|
||||
|
||||
// GetStatus gets com.canonical.dbusmenu.Status property.
|
||||
func (o *Dbusmenu) GetStatus(ctx context.Context) (status string, err error) {
|
||||
err = o.object.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, InterfaceDbusmenu, "Status").Store(&status)
|
||||
return
|
||||
}
|
||||
|
||||
// GetIconThemePath gets com.canonical.dbusmenu.IconThemePath property.
|
||||
func (o *Dbusmenu) GetIconThemePath(ctx context.Context) (iconThemePath []string, err error) {
|
||||
err = o.object.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, InterfaceDbusmenu, "IconThemePath").Store(&iconThemePath)
|
||||
return
|
||||
}
|
||||
|
||||
// Dbusmenu_ItemsPropertiesUpdatedSignal represents com.canonical.dbusmenu.ItemsPropertiesUpdated signal.
|
||||
type Dbusmenu_ItemsPropertiesUpdatedSignal struct {
|
||||
sender string
|
||||
Path dbus.ObjectPath
|
||||
Body *Dbusmenu_ItemsPropertiesUpdatedSignalBody
|
||||
}
|
||||
|
||||
// Name returns the signal's name.
|
||||
func (s *Dbusmenu_ItemsPropertiesUpdatedSignal) Name() string {
|
||||
return "ItemsPropertiesUpdated"
|
||||
}
|
||||
|
||||
// Interface returns the signal's interface.
|
||||
func (s *Dbusmenu_ItemsPropertiesUpdatedSignal) Interface() string {
|
||||
return InterfaceDbusmenu
|
||||
}
|
||||
|
||||
// Sender returns the signal's sender unique name.
|
||||
func (s *Dbusmenu_ItemsPropertiesUpdatedSignal) Sender() string {
|
||||
return s.sender
|
||||
}
|
||||
|
||||
func (s *Dbusmenu_ItemsPropertiesUpdatedSignal) path() dbus.ObjectPath {
|
||||
return s.Path
|
||||
}
|
||||
|
||||
func (s *Dbusmenu_ItemsPropertiesUpdatedSignal) values() []interface{} {
|
||||
return []interface{}{s.Body.UpdatedProps, s.Body.RemovedProps}
|
||||
}
|
||||
|
||||
// Dbusmenu_ItemsPropertiesUpdatedSignalBody is body container.
|
||||
type Dbusmenu_ItemsPropertiesUpdatedSignalBody struct {
|
||||
UpdatedProps []struct {
|
||||
V0 int32
|
||||
V1 map[string]dbus.Variant
|
||||
}
|
||||
RemovedProps []struct {
|
||||
V0 int32
|
||||
V1 []string
|
||||
}
|
||||
}
|
||||
|
||||
// Dbusmenu_LayoutUpdatedSignal represents com.canonical.dbusmenu.LayoutUpdated signal.
|
||||
type Dbusmenu_LayoutUpdatedSignal struct {
|
||||
sender string
|
||||
Path dbus.ObjectPath
|
||||
Body *Dbusmenu_LayoutUpdatedSignalBody
|
||||
}
|
||||
|
||||
// Name returns the signal's name.
|
||||
func (s *Dbusmenu_LayoutUpdatedSignal) Name() string {
|
||||
return "LayoutUpdated"
|
||||
}
|
||||
|
||||
// Interface returns the signal's interface.
|
||||
func (s *Dbusmenu_LayoutUpdatedSignal) Interface() string {
|
||||
return InterfaceDbusmenu
|
||||
}
|
||||
|
||||
// Sender returns the signal's sender unique name.
|
||||
func (s *Dbusmenu_LayoutUpdatedSignal) Sender() string {
|
||||
return s.sender
|
||||
}
|
||||
|
||||
func (s *Dbusmenu_LayoutUpdatedSignal) path() dbus.ObjectPath {
|
||||
return s.Path
|
||||
}
|
||||
|
||||
func (s *Dbusmenu_LayoutUpdatedSignal) values() []interface{} {
|
||||
return []interface{}{s.Body.Revision, s.Body.Parent}
|
||||
}
|
||||
|
||||
// Dbusmenu_LayoutUpdatedSignalBody is body container.
|
||||
type Dbusmenu_LayoutUpdatedSignalBody struct {
|
||||
Revision uint32
|
||||
Parent int32
|
||||
}
|
||||
|
||||
// Dbusmenu_ItemActivationRequestedSignal represents com.canonical.dbusmenu.ItemActivationRequested signal.
|
||||
type Dbusmenu_ItemActivationRequestedSignal struct {
|
||||
sender string
|
||||
Path dbus.ObjectPath
|
||||
Body *Dbusmenu_ItemActivationRequestedSignalBody
|
||||
}
|
||||
|
||||
// Name returns the signal's name.
|
||||
func (s *Dbusmenu_ItemActivationRequestedSignal) Name() string {
|
||||
return "ItemActivationRequested"
|
||||
}
|
||||
|
||||
// Interface returns the signal's interface.
|
||||
func (s *Dbusmenu_ItemActivationRequestedSignal) Interface() string {
|
||||
return InterfaceDbusmenu
|
||||
}
|
||||
|
||||
// Sender returns the signal's sender unique name.
|
||||
func (s *Dbusmenu_ItemActivationRequestedSignal) Sender() string {
|
||||
return s.sender
|
||||
}
|
||||
|
||||
func (s *Dbusmenu_ItemActivationRequestedSignal) path() dbus.ObjectPath {
|
||||
return s.Path
|
||||
}
|
||||
|
||||
func (s *Dbusmenu_ItemActivationRequestedSignal) values() []interface{} {
|
||||
return []interface{}{s.Body.Id, s.Body.Timestamp}
|
||||
}
|
||||
|
||||
// Dbusmenu_ItemActivationRequestedSignalBody is body container.
|
||||
type Dbusmenu_ItemActivationRequestedSignalBody struct {
|
||||
Id int32
|
||||
Timestamp uint32
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,3 +18,20 @@ func pngToImage(data []byte) (*image.RGBA, error) {
|
||||
draw.Draw(rgba, bounds, img, bounds.Min, draw.Src)
|
||||
return rgba, nil
|
||||
}
|
||||
|
||||
func ToARGB(img *image.RGBA) (int, int, []byte) {
|
||||
w, h := img.Bounds().Dx(), img.Bounds().Dy()
|
||||
data := make([]byte, w*h*4)
|
||||
i := 0
|
||||
for y := 0; y < h; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
r, g, b, a := img.At(x, y).RGBA()
|
||||
data[i] = byte(a)
|
||||
data[i+1] = byte(r)
|
||||
data[i+2] = byte(g)
|
||||
data[i+3] = byte(b)
|
||||
i += 4
|
||||
}
|
||||
}
|
||||
return w, h, data
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ func newMenuItem(label string) *MenuItem {
|
||||
|
||||
func newMenuItemSeparator() *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: uint(atomic.AddUintptr(&menuItemID, 1)),
|
||||
itemType: separator,
|
||||
}
|
||||
return result
|
||||
@@ -199,7 +200,9 @@ func (m *MenuItem) handleClick() {
|
||||
if m.itemType == checkbox {
|
||||
m.checked = !m.checked
|
||||
ctx.withChecked(m.checked)
|
||||
m.impl.setChecked(m.checked)
|
||||
if m.impl != nil {
|
||||
m.impl.setChecked(m.checked)
|
||||
}
|
||||
}
|
||||
if m.itemType == radio {
|
||||
for _, member := range m.radioGroupMembers {
|
||||
@@ -210,7 +213,9 @@ func (m *MenuItem) handleClick() {
|
||||
}
|
||||
m.checked = true
|
||||
ctx.withChecked(true)
|
||||
m.impl.setChecked(true)
|
||||
if m.impl != nil {
|
||||
m.impl.setChecked(true)
|
||||
}
|
||||
}
|
||||
if m.callback != nil {
|
||||
go m.callback(ctx)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user