feat: generate DBus code
This commit is contained in:
parent
9c7ca4aaa1
commit
cce25ca383
@ -1,3 +1,11 @@
|
|||||||
|
import com.jetbrains.plugin.structure.base.utils.createParentDirs
|
||||||
|
import org.freedesktop.dbus.utils.generator.InterfaceCodeGenerator
|
||||||
|
import org.jetbrains.intellij.platform.gradle.utils.asPath
|
||||||
|
import java.nio.file.Files
|
||||||
|
import kotlin.io.path.ExperimentalPathApi
|
||||||
|
import kotlin.io.path.createDirectories
|
||||||
|
import kotlin.io.path.deleteRecursively
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
kotlin("jvm") version "1.9.24"
|
kotlin("jvm") version "1.9.24"
|
||||||
@ -23,8 +31,9 @@ dependencies {
|
|||||||
intellijIdeaCommunity("242.20224.91")
|
intellijIdeaCommunity("242.20224.91")
|
||||||
instrumentationTools()
|
instrumentationTools()
|
||||||
}
|
}
|
||||||
implementation("io.gitlab.jfronny:commons-unsafe:2.0.0-SNAPSHOT")
|
|
||||||
extraResources(project(mapOf("path" to ":native", "configuration" to "results")))
|
extraResources(project(mapOf("path" to ":native", "configuration" to "results")))
|
||||||
|
implementation("io.gitlab.jfronny:commons-unsafe:2.0.0-SNAPSHOT")
|
||||||
|
implementation("com.github.hypfvieh:dbus-java-core:5.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
val copyExtraResources by tasks.creating(Copy::class) {
|
val copyExtraResources by tasks.creating(Copy::class) {
|
||||||
@ -35,17 +44,96 @@ val copyExtraResources by tasks.creating(Copy::class) {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
resources {
|
resources {
|
||||||
this.srcDir(copyExtraResources)
|
srcDir(copyExtraResources)
|
||||||
|
}
|
||||||
|
java {
|
||||||
|
srcDir(layout.buildDirectory.dir("generated/dbus/menu"))
|
||||||
|
srcDir(layout.buildDirectory.dir("generated/dbus/registrar"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RunToolTask : AbstractExecTask<RunToolTask>(RunToolTask::class.java) {
|
abstract class InterfaceGenerateTask : DefaultTask() {
|
||||||
@get:InputFile abstract val inputFile: RegularFileProperty
|
@get:InputFile abstract val inputFile: RegularFileProperty
|
||||||
@get:OutputFile abstract val outputFile: RegularFileProperty
|
@get:Input abstract val objectPath: Property<String>
|
||||||
|
@get:Input abstract val busName: Property<String>
|
||||||
|
@get:OutputDirectory abstract val outputFile: DirectoryProperty
|
||||||
|
@TaskAction fun generate() {
|
||||||
|
val input = inputFile.get().asPath
|
||||||
|
val introspectionData = Files.readString(input)
|
||||||
|
val output = outputFile.get().asPath
|
||||||
|
val generator = InterfaceCodeGenerator(
|
||||||
|
false,
|
||||||
|
introspectionData,
|
||||||
|
objectPath.get(),
|
||||||
|
busName.get(),
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
val analyze = generator.analyze(true)!!
|
||||||
|
if (analyze.isEmpty()) throw IllegalStateException("No interfaces found")
|
||||||
|
@OptIn(ExperimentalPathApi::class)
|
||||||
|
output.deleteRecursively()
|
||||||
|
output.createDirectories()
|
||||||
|
val regex = Regex("List<org\\.freedesktop\\.dbus\\.Struct<Integer>, ([^_\\n]+)>")
|
||||||
|
val memory = LinkedHashMap<String, String>()
|
||||||
|
for (entry in analyze) {
|
||||||
|
if (entry.key.path.equals("/.java")) continue // Skip incorrectly generated file
|
||||||
|
val pth = output.resolve(entry.key.path.trimStart('/'))
|
||||||
|
pth.createParentDirs()
|
||||||
|
// Fix the incorrect generic type
|
||||||
|
Files.writeString(pth, entry.value.replace(regex) { match ->
|
||||||
|
memory.computeIfAbsent(match.groups[1]!!.value) { type ->
|
||||||
|
val name = "Struct${memory.size + 1}"
|
||||||
|
Files.writeString(output.resolve("com/canonical").resolve("$name.java"), """
|
||||||
|
package com.canonical;
|
||||||
|
|
||||||
|
import org.freedesktop.dbus.Struct;
|
||||||
|
import org.freedesktop.dbus.annotations.Position;
|
||||||
|
import org.freedesktop.dbus.types.Variant;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class $name extends Struct {
|
||||||
|
@Position(0) public final int a;
|
||||||
|
@Position(1) public final $type b;
|
||||||
|
|
||||||
|
public $name(int a, $type b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".trimIndent())
|
||||||
|
name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
val generateDbus by registering(InterfaceGenerateTask::class) {
|
||||||
|
group = "custom"
|
||||||
|
objectPath = "/"
|
||||||
|
busName = ""
|
||||||
|
inputFile = file("src/main/protocols/dbus-menu.xml")
|
||||||
|
outputFile = layout.buildDirectory.dir("generated/dbus/menu")
|
||||||
|
}
|
||||||
|
val generateDbusRegistrar by registering(InterfaceGenerateTask::class) {
|
||||||
|
group = "custom"
|
||||||
|
objectPath = "/"
|
||||||
|
busName = ""
|
||||||
|
inputFile = file("src/main/protocols/com.canonical.AppMenu.Registrar.xml")
|
||||||
|
outputFile = layout.buildDirectory.dir("generated/dbus/registrar")
|
||||||
|
}
|
||||||
|
compileJava {
|
||||||
|
dependsOn(generateDbus, generateDbusRegistrar)
|
||||||
|
}
|
||||||
|
compileKotlin {
|
||||||
|
dependsOn(generateDbus, generateDbusRegistrar)
|
||||||
|
}
|
||||||
|
|
||||||
// Set the JVM compatibility versions
|
// Set the JVM compatibility versions
|
||||||
withType<JavaCompile> {
|
withType<JavaCompile> {
|
||||||
sourceCompatibility = "21"
|
sourceCompatibility = "21"
|
||||||
|
@ -24,8 +24,8 @@ library {
|
|||||||
else if (osFamily.isWindows) compileTask.includes.from("$dir/win32")
|
else if (osFamily.isWindows) compileTask.includes.from("$dir/win32")
|
||||||
|
|
||||||
compileTask.source.from(fileTree(mapOf("dir" to "src/main/c", "include" to "**/*.c")))
|
compileTask.source.from(fileTree(mapOf("dir" to "src/main/c", "include" to "**/*.c")))
|
||||||
compileTask.source.from(fileTree(mapOf("dir" to layout.buildDirectory.dir("generated"), "include" to "**/*.c")))
|
compileTask.source.from(fileTree(mapOf("dir" to layout.buildDirectory.dir("generated/wayland"), "include" to "**/*.c")))
|
||||||
compileTask.includes.from(layout.buildDirectory.dir("generated"))
|
compileTask.includes.from(layout.buildDirectory.dir("generated/wayland"))
|
||||||
|
|
||||||
if (toolChain is VisualCpp) {
|
if (toolChain is VisualCpp) {
|
||||||
compileTask.compilerArgs.addAll("/TC")
|
compileTask.compilerArgs.addAll("/TC")
|
||||||
@ -58,13 +58,13 @@ tasks {
|
|||||||
val generateAppmenuHeader by registering(RunToolTask::class) {
|
val generateAppmenuHeader by registering(RunToolTask::class) {
|
||||||
group = "custom"
|
group = "custom"
|
||||||
inputFile = file("src/main/protocols/appmenu.xml")
|
inputFile = file("src/main/protocols/appmenu.xml")
|
||||||
outputFile = layout.buildDirectory.file("generated/appmenu.h")
|
outputFile = layout.buildDirectory.file("generated/wayland/appmenu.h")
|
||||||
commandLine("wayland-scanner", "client-header", inputFile.asFile.get().absolutePath, outputFile.asFile.get().absolutePath)
|
commandLine("wayland-scanner", "client-header", inputFile.asFile.get().absolutePath, outputFile.asFile.get().absolutePath)
|
||||||
}
|
}
|
||||||
val generateAppmenuGlue by registering(RunToolTask::class) {
|
val generateAppmenuGlue by registering(RunToolTask::class) {
|
||||||
group = "custom"
|
group = "custom"
|
||||||
inputFile = file("src/main/protocols/appmenu.xml")
|
inputFile = file("src/main/protocols/appmenu.xml")
|
||||||
outputFile = layout.buildDirectory.file("generated/appmenu.c")
|
outputFile = layout.buildDirectory.file("generated/wayland/appmenu.c")
|
||||||
commandLine("wayland-scanner", "private-code", inputFile.asFile.get().absolutePath, outputFile.asFile.get().absolutePath)
|
commandLine("wayland-scanner", "private-code", inputFile.asFile.get().absolutePath, outputFile.asFile.get().absolutePath)
|
||||||
}
|
}
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
|
@ -5,6 +5,15 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("com.github.hypfvieh:dbus-java-utils:5.0.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rootProject.name = "globalmenu"
|
rootProject.name = "globalmenu"
|
||||||
|
|
||||||
include("native")
|
include("native")
|
@ -10,17 +10,24 @@ public class Native {
|
|||||||
public native void destroy(long ptr);
|
public native void destroy(long ptr);
|
||||||
public native void setAddress(long ptr, String serviceName, String objectPath);
|
public native void setAddress(long ptr, String serviceName, String objectPath);
|
||||||
|
|
||||||
|
private static final boolean supported;
|
||||||
static {
|
static {
|
||||||
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
if (!System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||||
|
supported = false;
|
||||||
|
} else {
|
||||||
try (InputStream is = Native.class.getResourceAsStream("/libnative.so")) {
|
try (InputStream is = Native.class.getResourceAsStream("/libnative.so")) {
|
||||||
Path path = Files.createTempFile("libnative", ".so");
|
Path path = Files.createTempFile("libnative", ".so");
|
||||||
Files.copy(is, path, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(is, path, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||||
System.load(path.toString());
|
System.load(path.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
supported = false;
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} else {
|
supported = true;
|
||||||
throw new RuntimeException("Linux is required for the global menu plugin");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSupported() {
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import javax.swing.JMenuBar
|
|||||||
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
||||||
override fun applicationActivated(ideFrame: IdeFrame) {
|
override fun applicationActivated(ideFrame: IdeFrame) {
|
||||||
super.applicationActivated(ideFrame)
|
super.applicationActivated(ideFrame)
|
||||||
|
if (!GlobalMenu.Native.isSupported) return
|
||||||
ideFrame.project?.let { project ->
|
ideFrame.project?.let { project ->
|
||||||
println(ideFrame.javaClass)
|
println(ideFrame.javaClass)
|
||||||
if (ideFrame is ProjectFrameHelper) {
|
if (ideFrame is ProjectFrameHelper) {
|
||||||
|
@ -4,6 +4,8 @@ import com.intellij.ide.AppLifecycleListener
|
|||||||
|
|
||||||
class InitializationComponent : AppLifecycleListener {
|
class InitializationComponent : AppLifecycleListener {
|
||||||
override fun appFrameCreated(commandLineArgs: MutableList<String>) {
|
override fun appFrameCreated(commandLineArgs: MutableList<String>) {
|
||||||
|
if (GlobalMenu.Native.isSupported) {
|
||||||
GlobalMenu.Native.init(getDisplayPtr())
|
GlobalMenu.Native.init(getDisplayPtr())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
56
src/main/protocols/com.canonical.AppMenu.Registrar.xml
Normal file
56
src/main/protocols/com.canonical.AppMenu.Registrar.xml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
|
||||||
|
<dox:d><![CDATA[
|
||||||
|
@mainpage
|
||||||
|
|
||||||
|
An interface to register menus that are associated with a window in an application. The
|
||||||
|
main interface is docuemented here: @ref com::canonical::AppMenu::Registrar.
|
||||||
|
|
||||||
|
The actual menus are transported using the dbusmenu protocol which is available
|
||||||
|
here: @ref com::canonical::dbusmenu.
|
||||||
|
]]></dox:d>
|
||||||
|
<interface name="com.canonical.AppMenu.Registrar" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
|
||||||
|
<dox:d>
|
||||||
|
An interface to register a menu from an application's window to be displayed in another
|
||||||
|
window. This manages that association between XWindow Window IDs and the dbus
|
||||||
|
address and object that provides the menu using the dbusmenu dbus interface.
|
||||||
|
</dox:d>
|
||||||
|
<method name="RegisterWindow">
|
||||||
|
<dox:d><![CDATA[
|
||||||
|
Associates a dbusmenu with a window
|
||||||
|
|
||||||
|
/note this method assumes that the connection from the caller is the DBus connection
|
||||||
|
to use for the object. Applications that use multiple DBus connections will need to
|
||||||
|
ensure this method is called with the same connection that implmenets the object.
|
||||||
|
]]></dox:d>
|
||||||
|
<arg name="windowId" type="u" direction="in">
|
||||||
|
<dox:d>The XWindow ID of the window</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg name="menuObjectPath" type="o" direction="in">
|
||||||
|
<dox:d>The object on the dbus interface implementing the dbusmenu interface</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
<method name="UnregisterWindow">
|
||||||
|
<dox:d>
|
||||||
|
A method to allow removing a window from the database. Windows will also be removed
|
||||||
|
when the client drops off DBus so this is not required. It is polite though. And
|
||||||
|
important for testing.
|
||||||
|
</dox:d>
|
||||||
|
<arg name="windowId" type="u" direction="in">
|
||||||
|
<dox:d>The XWindow ID of the window</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
<method name="GetMenuForWindow">
|
||||||
|
<dox:d>Gets the registered menu for a given window ID.</dox:d>
|
||||||
|
<arg name="windowId" type="u" direction="in">
|
||||||
|
<dox:d>The XWindow ID of the window to get</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg name="service" type="s" direction="out">
|
||||||
|
<dox:d>The address of the connection on DBus (e.g. :1.23 or org.example.service)</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg name="menuObjectPath" type="o" direction="out">
|
||||||
|
<dox:d>The path to the object which implements the com.canonical.dbusmenu interface.</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
437
src/main/protocols/dbus-menu.xml
Normal file
437
src/main/protocols/dbus-menu.xml
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
A library to allow applications to provide simple indications of
|
||||||
|
information to be displayed to users of the application through the
|
||||||
|
interface shell.
|
||||||
|
|
||||||
|
Copyright 2009 Canonical Ltd.
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Ted Gould <ted@canonical.com>
|
||||||
|
Aurélien Gâteau <aurelien.gateau@canonical.com>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of either or both of the following licenses:
|
||||||
|
|
||||||
|
1) the GNU Lesser General Public License version 3, as published by the
|
||||||
|
Free Software Foundation; and/or
|
||||||
|
2) the GNU Lesser General Public License version 2.1, as published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||||
|
MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the applicable version of the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of both the GNU Lesser General Public
|
||||||
|
License version 3 and version 2.1 along with this program. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>
|
||||||
|
-->
|
||||||
|
<node name="/" xmlns:dox="http://www.canonical.com/dbus/dox.dtd">
|
||||||
|
<dox:d><![CDATA[
|
||||||
|
@mainpage
|
||||||
|
|
||||||
|
The goal of DBusMenu is to expose menus on DBus.
|
||||||
|
|
||||||
|
Main interface is documented here: @ref com::canonical::dbusmenu
|
||||||
|
]]></dox:d>
|
||||||
|
<interface name="com.canonical.dbusmenu">
|
||||||
|
<dox:d><![CDATA[
|
||||||
|
A DBus interface to expose menus on DBus.
|
||||||
|
|
||||||
|
Menu items are represented with a unique numeric id and a dictionary of
|
||||||
|
properties.
|
||||||
|
|
||||||
|
To reduce the amount of DBus traffic, a property should only be returned
|
||||||
|
if its value is not the default value.
|
||||||
|
|
||||||
|
Available properties are:
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Default Value</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>type</td>
|
||||||
|
<td>String</td>
|
||||||
|
<td>Can be one of:
|
||||||
|
- "standard": an item which can be clicked to trigger an action or
|
||||||
|
show another menu
|
||||||
|
- "separator": a separator
|
||||||
|
|
||||||
|
Vendor specific types can be added by prefixing them with
|
||||||
|
"x-<vendor>-".
|
||||||
|
</td>
|
||||||
|
<td>"standard"</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>label</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>Text of the item, except that:
|
||||||
|
-# two consecutive underscore characters "__" are displayed as a
|
||||||
|
single underscore,
|
||||||
|
-# any remaining underscore characters are not displayed at all,
|
||||||
|
-# the first of those remaining underscore characters (unless it is
|
||||||
|
the last character in the string) indicates that the following
|
||||||
|
character is the access key.
|
||||||
|
</td>
|
||||||
|
<td>""</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>enabled</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>Whether the item can be activated or not.</td>
|
||||||
|
<td>true</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>visible</td>
|
||||||
|
<td>boolean</td>
|
||||||
|
<td>True if the item is visible in the menu.</td>
|
||||||
|
<td>true</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>icon-name</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>Icon name of the item, following the freedesktop.org icon spec.</td>
|
||||||
|
<td>""</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>icon-data</td>
|
||||||
|
<td>binary</td>
|
||||||
|
<td>PNG data of the icon.</td>
|
||||||
|
<td>Empty</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>shortcut</td>
|
||||||
|
<td>array of arrays of strings</td>
|
||||||
|
<td>The shortcut of the item. Each array represents the key press
|
||||||
|
in the list of keypresses. Each list of strings contains a list of
|
||||||
|
modifiers and then the key that is used. The modifier strings
|
||||||
|
allowed are: "Control", "Alt", "Shift" and "Super".
|
||||||
|
|
||||||
|
- A simple shortcut like Ctrl+S is represented as:
|
||||||
|
[["Control", "S"]]
|
||||||
|
- A complex shortcut like Ctrl+Q, Alt+X is represented as:
|
||||||
|
[["Control", "Q"], ["Alt", "X"]]</td>
|
||||||
|
<td>Empty</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>toggle-type</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>
|
||||||
|
If the item can be toggled, this property should be set to:
|
||||||
|
- "checkmark": Item is an independent togglable item
|
||||||
|
- "radio": Item is part of a group where only one item can be
|
||||||
|
toggled at a time
|
||||||
|
- "": Item cannot be toggled
|
||||||
|
</td>
|
||||||
|
<td>""</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>toggle-state</td>
|
||||||
|
<td>int</td>
|
||||||
|
<td>
|
||||||
|
Describe the current state of a "togglable" item. Can be one of:
|
||||||
|
- 0 = off
|
||||||
|
- 1 = on
|
||||||
|
- anything else = indeterminate
|
||||||
|
|
||||||
|
Note:
|
||||||
|
The implementation does not itself handle ensuring that only one
|
||||||
|
item in a radio group is set to "on", or that a group does not have
|
||||||
|
"on" and "indeterminate" items simultaneously; maintaining this
|
||||||
|
policy is up to the toolkit wrappers.
|
||||||
|
</td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>children-display</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>
|
||||||
|
If the menu item has children this property should be set to
|
||||||
|
"submenu".
|
||||||
|
</td>
|
||||||
|
<td>""</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>disposition</td>
|
||||||
|
<td>string</td>
|
||||||
|
<td>
|
||||||
|
How the menuitem feels the information it's displaying to the
|
||||||
|
user should be presented.
|
||||||
|
- "normal" a standard menu item
|
||||||
|
- "informative" providing additional information to the user
|
||||||
|
- "warning" looking at potentially harmful results
|
||||||
|
- "alert" something bad could potentially happen
|
||||||
|
</td>
|
||||||
|
<td>"normal"</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
Vendor specific properties can be added by prefixing them with
|
||||||
|
"x-<vendor>-".
|
||||||
|
]]></dox:d>
|
||||||
|
|
||||||
|
<!-- Properties -->
|
||||||
|
<property name="Version" type="u" access="read">
|
||||||
|
<dox:d>
|
||||||
|
Provides the version of the DBusmenu API that this API is
|
||||||
|
implementing.
|
||||||
|
</dox:d>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="TextDirection" type="s" access="read">
|
||||||
|
<dox:d>
|
||||||
|
Represents the way the text direction of the application. This
|
||||||
|
allows the server to handle mismatches intelligently. For left-
|
||||||
|
to-right the string is "ltr" for right-to-left it is "rtl".
|
||||||
|
</dox:d>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="Status" type="s" access="read">
|
||||||
|
<dox:d>
|
||||||
|
Tells if the menus are in a normal state or they believe that they
|
||||||
|
could use some attention. Cases for showing them would be if help
|
||||||
|
were referring to them or they accessors were being highlighted.
|
||||||
|
This property can have two values: "normal" in almost all cases and
|
||||||
|
"notice" when they should have a higher priority to be shown.
|
||||||
|
</dox:d>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="IconThemePath" type="as" access="read">
|
||||||
|
<dox:d>
|
||||||
|
A list of directories that should be used for finding icons using
|
||||||
|
the icon naming spec. Idealy there should only be one for the icon
|
||||||
|
theme, but additional ones are often added by applications for
|
||||||
|
app specific icons.
|
||||||
|
</dox:d>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- Functions -->
|
||||||
|
|
||||||
|
<method name="GetLayout">
|
||||||
|
<dox:d>
|
||||||
|
Provides the layout and propertiers that are attached to the entries
|
||||||
|
that are in the layout. It only gives the items that are children
|
||||||
|
of the item that is specified in @a parentId. It will return all of the
|
||||||
|
properties or specific ones depending of the value in @a propertyNames.
|
||||||
|
|
||||||
|
The format is recursive, where the second 'v' is in the same format
|
||||||
|
as the original 'a(ia{sv}av)'. Its content depends on the value
|
||||||
|
of @a recursionDepth.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="i" name="parentId" direction="in">
|
||||||
|
<dox:d>The ID of the parent node for the layout. For
|
||||||
|
grabbing the layout from the root node use zero.</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="i" name="recursionDepth" direction="in">
|
||||||
|
<dox:d>
|
||||||
|
The amount of levels of recursion to use. This affects the
|
||||||
|
content of the second variant array.
|
||||||
|
- -1: deliver all the items under the @a parentId.
|
||||||
|
- 0: no recursion, the array will be empty.
|
||||||
|
- n: array will contains items up to 'n' level depth.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="as" name="propertyNames" direction="in" >
|
||||||
|
<dox:d>
|
||||||
|
The list of item properties we are
|
||||||
|
interested in. If there are no entries in the list all of
|
||||||
|
the properties will be sent.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="u" name="revision" direction="out">
|
||||||
|
<dox:d>The revision number of the layout. For matching
|
||||||
|
with layoutUpdated signals.</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="(ia{sv}av)" name="layout" direction="out">
|
||||||
|
<dox:d>The layout, as a recursive structure.</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="GetGroupProperties">
|
||||||
|
<dox:d>
|
||||||
|
Returns the list of items which are children of @a parentId.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="ai" name="ids" direction="in" >
|
||||||
|
<dox:d>
|
||||||
|
A list of ids that we should be finding the properties
|
||||||
|
on. If the list is empty, all menu items should be sent.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="as" name="propertyNames" direction="in" >
|
||||||
|
<dox:d>
|
||||||
|
The list of item properties we are
|
||||||
|
interested in. If there are no entries in the list all of
|
||||||
|
the properties will be sent.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="a(ia{sv})" name="properties" direction="out" >
|
||||||
|
<dox:d>
|
||||||
|
An array of property values.
|
||||||
|
An item in this area is represented as a struct following
|
||||||
|
this format:
|
||||||
|
@li id unsigned the item id
|
||||||
|
@li properties map(string => variant) the requested item properties
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="GetProperty">
|
||||||
|
<dox:d>
|
||||||
|
Get a signal property on a single item. This is not useful if you're
|
||||||
|
going to implement this interface, it should only be used if you're
|
||||||
|
debugging via a commandline tool.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="i" name="id" direction="in">
|
||||||
|
<dox:d>the id of the item which received the event</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="s" name="name" direction="in">
|
||||||
|
<dox:d>the name of the property to get</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="v" name="value" direction="out">
|
||||||
|
<dox:d>the value of the property</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="Event">
|
||||||
|
<dox:d><![CDATA[
|
||||||
|
This is called by the applet to notify the application an event happened on a
|
||||||
|
menu item.
|
||||||
|
|
||||||
|
@a type can be one of the following:
|
||||||
|
|
||||||
|
@li "clicked"
|
||||||
|
@li "hovered"
|
||||||
|
@li "opened"
|
||||||
|
@li "closed"
|
||||||
|
|
||||||
|
Vendor specific events can be added by prefixing them with "x-<vendor>-"
|
||||||
|
]]></dox:d>
|
||||||
|
<arg type="i" name="id" direction="in" >
|
||||||
|
<dox:d>the id of the item which received the event</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="s" name="eventId" direction="in" >
|
||||||
|
<dox:d>the type of event</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="v" name="data" direction="in" >
|
||||||
|
<dox:d>event-specific data</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="u" name="timestamp" direction="in" >
|
||||||
|
<dox:d>The time that the event occured if available or the time the message was sent if not</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="EventGroup">
|
||||||
|
<dox:d>
|
||||||
|
Used to pass a set of events as a single message for possibily several
|
||||||
|
different menuitems. This is done to optimize DBus traffic.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="a(isvu)" name="events" direction="in">
|
||||||
|
<dox:d>
|
||||||
|
An array of all the events that should be passed. This tuple should
|
||||||
|
match the parameters of the 'Event' signal. Which is roughly:
|
||||||
|
id, eventID, data and timestamp.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="ai" name="idErrors" direction="out">
|
||||||
|
<dox:d>
|
||||||
|
I list of menuitem IDs that couldn't be found. If none of the ones
|
||||||
|
in the list can be found, a DBus error is returned.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="AboutToShow">
|
||||||
|
<dox:d>
|
||||||
|
This is called by the applet to notify the application that it is about
|
||||||
|
to show the menu under the specified item.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="i" name="id" direction="in">
|
||||||
|
<dox:d>
|
||||||
|
Which menu item represents the parent of the item about to be shown.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="b" name="needUpdate" direction="out">
|
||||||
|
<dox:d>
|
||||||
|
Whether this AboutToShow event should result in the menu being updated.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="AboutToShowGroup">
|
||||||
|
<dox:d>
|
||||||
|
A function to tell several menus being shown that they are about to
|
||||||
|
be shown to the user. This is likely only useful for programitc purposes
|
||||||
|
so while the return values are returned, in general, the singular function
|
||||||
|
should be used in most user interacation scenarios.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="ai" name="ids" direction="in">
|
||||||
|
<dox:d>
|
||||||
|
The IDs of the menu items who's submenus are being shown.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="ai" name="updatesNeeded" direction="out">
|
||||||
|
<dox:d>
|
||||||
|
The IDs of the menus that need updates. Note: if no update information
|
||||||
|
is needed the DBus message should set the no reply flag.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="ai" name="idErrors" direction="out">
|
||||||
|
<dox:d>
|
||||||
|
I list of menuitem IDs that couldn't be found. If none of the ones
|
||||||
|
in the list can be found, a DBus error is returned.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!-- Signals -->
|
||||||
|
<signal name="ItemsPropertiesUpdated">
|
||||||
|
<dox:d>
|
||||||
|
Triggered when there are lots of property updates across many items
|
||||||
|
so they all get grouped into a single dbus message. The format is
|
||||||
|
the ID of the item with a hashtable of names and values for those
|
||||||
|
properties.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="a(ia{sv})" name="updatedProps" direction="out" />
|
||||||
|
<arg type="a(ias)" name="removedProps" direction="out" />
|
||||||
|
</signal>
|
||||||
|
<signal name="LayoutUpdated">
|
||||||
|
<dox:d>
|
||||||
|
Triggered by the application to notify display of a layout update, up to
|
||||||
|
revision
|
||||||
|
</dox:d>
|
||||||
|
<arg type="u" name="revision" direction="out" >
|
||||||
|
<dox:d>The revision of the layout that we're currently on</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="i" name="parent" direction="out" >
|
||||||
|
<dox:d>
|
||||||
|
If the layout update is only of a subtree, this is the
|
||||||
|
parent item for the entries that have changed. It is zero if
|
||||||
|
the whole layout should be considered invalid.
|
||||||
|
</dox:d>
|
||||||
|
</arg>
|
||||||
|
</signal>
|
||||||
|
<signal name="ItemActivationRequested">
|
||||||
|
<dox:d>
|
||||||
|
The server is requesting that all clients displaying this
|
||||||
|
menu open it to the user. This would be for things like
|
||||||
|
hotkeys that when the user presses them the menu should
|
||||||
|
open and display itself to the user.
|
||||||
|
</dox:d>
|
||||||
|
<arg type="i" name="id" direction="out" >
|
||||||
|
<dox:d>ID of the menu that should be activated</dox:d>
|
||||||
|
</arg>
|
||||||
|
<arg type="u" name="timestamp" direction="out" >
|
||||||
|
<dox:d>The time that the event occured</dox:d>
|
||||||
|
</arg>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<!-- End of interesting stuff -->
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
</node>
|
Loading…
Reference in New Issue
Block a user