Skip to content

Instantly share code, notes, and snippets.

@MCJack123
Created June 25, 2024 20:24
Show Gist options
  • Save MCJack123/e0651868837b819c28290b26c410ddb5 to your computer and use it in GitHub Desktop.
Save MCJack123/e0651868837b819c28290b26c410ddb5 to your computer and use it in GitHub Desktop.
Firefox patch to use (old) KDE appmenu protocol on Wayland if xdg-dbus-annotation fails
--- /dev/null
+++ b/widget/gtk/wayland/kwin-appmenu-v1-client-protocol.h
@@ -1,0 +1,189 @@
+/* Generated by wayland-scanner 1.23.0 */
+
+#ifndef APPMENU_CLIENT_PROTOCOL_H
+#define APPMENU_CLIENT_PROTOCOL_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @page page_appmenu The appmenu protocol
+ * @section page_ifaces_appmenu Interfaces
+ * - @subpage page_iface_org_kde_kwin_appmenu_manager - appmenu dbus address interface
+ * - @subpage page_iface_org_kde_kwin_appmenu - appmenu dbus address interface
+ * @section page_copyright_appmenu Copyright
+ * <pre>
+ *
+ * SPDX-FileCopyrightText: 2017 David Edmundson
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * </pre>
+ */
+struct org_kde_kwin_appmenu;
+struct org_kde_kwin_appmenu_manager;
+struct wl_surface;
+
+#ifndef ORG_KDE_KWIN_APPMENU_MANAGER_INTERFACE
+#define ORG_KDE_KWIN_APPMENU_MANAGER_INTERFACE
+/**
+ * @page page_iface_org_kde_kwin_appmenu_manager org_kde_kwin_appmenu_manager
+ * @section page_iface_org_kde_kwin_appmenu_manager_desc Description
+ *
+ * This interface allows a client to link a window (or wl_surface) to an com.canonical.dbusmenu
+ * interface registered on DBus.
+ * @section page_iface_org_kde_kwin_appmenu_manager_api API
+ * See @ref iface_org_kde_kwin_appmenu_manager.
+ */
+/**
+ * @defgroup iface_org_kde_kwin_appmenu_manager The org_kde_kwin_appmenu_manager interface
+ *
+ * This interface allows a client to link a window (or wl_surface) to an com.canonical.dbusmenu
+ * interface registered on DBus.
+ */
+extern const struct wl_interface org_kde_kwin_appmenu_manager_interface;
+#endif
+#ifndef ORG_KDE_KWIN_APPMENU_INTERFACE
+#define ORG_KDE_KWIN_APPMENU_INTERFACE
+/**
+ * @page page_iface_org_kde_kwin_appmenu org_kde_kwin_appmenu
+ * @section page_iface_org_kde_kwin_appmenu_desc Description
+ *
+ * The DBus service name and object path where the appmenu interface is present
+ * The object should be registered on the session bus before sending this request.
+ * If not applicable, clients should remove this object.
+ * @section page_iface_org_kde_kwin_appmenu_api API
+ * See @ref iface_org_kde_kwin_appmenu.
+ */
+/**
+ * @defgroup iface_org_kde_kwin_appmenu The org_kde_kwin_appmenu interface
+ *
+ * The DBus service name and object path where the appmenu interface is present
+ * The object should be registered on the session bus before sending this request.
+ * If not applicable, clients should remove this object.
+ */
+extern const struct wl_interface org_kde_kwin_appmenu_interface;
+#endif
+
+#define ORG_KDE_KWIN_APPMENU_MANAGER_CREATE 0
+
+
+/**
+ * @ingroup iface_org_kde_kwin_appmenu_manager
+ */
+#define ORG_KDE_KWIN_APPMENU_MANAGER_CREATE_SINCE_VERSION 1
+
+/** @ingroup iface_org_kde_kwin_appmenu_manager */
+static inline void
+org_kde_kwin_appmenu_manager_set_user_data(struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) org_kde_kwin_appmenu_manager, user_data);
+}
+
+/** @ingroup iface_org_kde_kwin_appmenu_manager */
+static inline void *
+org_kde_kwin_appmenu_manager_get_user_data(struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) org_kde_kwin_appmenu_manager);
+}
+
+static inline uint32_t
+org_kde_kwin_appmenu_manager_get_version(struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager)
+{
+ return wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_appmenu_manager);
+}
+
+/** @ingroup iface_org_kde_kwin_appmenu_manager */
+static inline void
+org_kde_kwin_appmenu_manager_destroy(struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager)
+{
+ wl_proxy_destroy((struct wl_proxy *) org_kde_kwin_appmenu_manager);
+}
+
+/**
+ * @ingroup iface_org_kde_kwin_appmenu_manager
+ */
+static inline struct org_kde_kwin_appmenu *
+org_kde_kwin_appmenu_manager_create(struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager, struct wl_surface *surface)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_marshal_flags((struct wl_proxy *) org_kde_kwin_appmenu_manager,
+ ORG_KDE_KWIN_APPMENU_MANAGER_CREATE, &org_kde_kwin_appmenu_interface, wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_appmenu_manager), 0, NULL, surface);
+
+ return (struct org_kde_kwin_appmenu *) id;
+}
+
+#define ORG_KDE_KWIN_APPMENU_SET_ADDRESS 0
+#define ORG_KDE_KWIN_APPMENU_RELEASE 1
+
+
+/**
+ * @ingroup iface_org_kde_kwin_appmenu
+ */
+#define ORG_KDE_KWIN_APPMENU_SET_ADDRESS_SINCE_VERSION 1
+/**
+ * @ingroup iface_org_kde_kwin_appmenu
+ */
+#define ORG_KDE_KWIN_APPMENU_RELEASE_SINCE_VERSION 1
+
+/** @ingroup iface_org_kde_kwin_appmenu */
+static inline void
+org_kde_kwin_appmenu_set_user_data(struct org_kde_kwin_appmenu *org_kde_kwin_appmenu, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) org_kde_kwin_appmenu, user_data);
+}
+
+/** @ingroup iface_org_kde_kwin_appmenu */
+static inline void *
+org_kde_kwin_appmenu_get_user_data(struct org_kde_kwin_appmenu *org_kde_kwin_appmenu)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) org_kde_kwin_appmenu);
+}
+
+static inline uint32_t
+org_kde_kwin_appmenu_get_version(struct org_kde_kwin_appmenu *org_kde_kwin_appmenu)
+{
+ return wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_appmenu);
+}
+
+/** @ingroup iface_org_kde_kwin_appmenu */
+static inline void
+org_kde_kwin_appmenu_destroy(struct org_kde_kwin_appmenu *org_kde_kwin_appmenu)
+{
+ wl_proxy_destroy((struct wl_proxy *) org_kde_kwin_appmenu);
+}
+
+/**
+ * @ingroup iface_org_kde_kwin_appmenu
+ *
+ * Set or update the service name and object path.
+ * Strings should be formatted in Latin-1 matching the relevant DBus specifications.
+ */
+static inline void
+org_kde_kwin_appmenu_set_address(struct org_kde_kwin_appmenu *org_kde_kwin_appmenu, const char *service_name, const char *object_path)
+{
+ wl_proxy_marshal_flags((struct wl_proxy *) org_kde_kwin_appmenu,
+ ORG_KDE_KWIN_APPMENU_SET_ADDRESS, NULL, wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_appmenu), 0, service_name, object_path);
+}
+
+/**
+ * @ingroup iface_org_kde_kwin_appmenu
+ */
+static inline void
+org_kde_kwin_appmenu_release(struct org_kde_kwin_appmenu *org_kde_kwin_appmenu)
+{
+ wl_proxy_marshal_flags((struct wl_proxy *) org_kde_kwin_appmenu,
+ ORG_KDE_KWIN_APPMENU_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_appmenu), WL_MARSHAL_FLAG_DESTROY);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
--- /dev/null
+++ b/widget/gtk/wayland/kwin-appmenu-v1-protocol.c
@@ -1,0 +1,57 @@
+/* Generated by wayland-scanner 1.23.0 */
+
+/*
+ * SPDX-FileCopyrightText: 2017 David Edmundson
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+#ifndef __has_attribute
+# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
+#endif
+
+#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
+#define WL_PRIVATE __attribute__ ((visibility("hidden")))
+#else
+#define WL_PRIVATE
+#endif
+
+extern const struct wl_interface org_kde_kwin_appmenu_interface;
+#pragma GCC visibility push(default)
+extern const struct wl_interface wl_surface_interface;
+#pragma GCC visibility pop
+
+static const struct wl_interface *appmenu_types[] = {
+ NULL,
+ NULL,
+ &org_kde_kwin_appmenu_interface,
+ &wl_surface_interface,
+};
+
+static const struct wl_message org_kde_kwin_appmenu_manager_requests[] = {
+ { "create", "no", appmenu_types + 2 },
+};
+
+WL_PRIVATE const struct wl_interface org_kde_kwin_appmenu_manager_interface = {
+ "org_kde_kwin_appmenu_manager", 1,
+ 1, org_kde_kwin_appmenu_manager_requests,
+ 0, NULL,
+};
+
+static const struct wl_message org_kde_kwin_appmenu_requests[] = {
+ { "set_address", "ss", appmenu_types + 0 },
+ { "release", "", appmenu_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface org_kde_kwin_appmenu_interface = {
+ "org_kde_kwin_appmenu", 1,
+ 2, org_kde_kwin_appmenu_requests,
+ 0, NULL,
+};
+
+
--- a/widget/gtk/wayland/moz.build
+++ b/widget/gtk/wayland/moz.build
@@ -10,6 +10,7 @@
SOURCES += [
"fractional-scale-v1-protocol.c",
"idle-inhibit-unstable-v1-protocol.c",
+ "kwin-appmenu-v1-protocol.c",
"linux-dmabuf-unstable-v1-protocol.c",
"pointer-constraints-unstable-v1-protocol.c",
"relative-pointer-unstable-v1-protocol.c",
@@ -21,6 +22,7 @@
EXPORTS.mozilla.widget += [
"fractional-scale-v1-client-protocol.h",
"idle-inhibit-unstable-v1-client-protocol.h",
+ "kwin-appmenu-v1-client-protocol.h",
"linux-dmabuf-unstable-v1-client-protocol.h",
"pointer-constraints-unstable-v1-client-protocol.h",
"relative-pointer-unstable-v1-client-protocol.h",
--- a/widget/gtk/nsWaylandDisplay.cpp
+++ b/widget/gtk/nsWaylandDisplay.cpp
@@ -149,6 +149,10 @@
auto* manager = WaylandRegistryBind<wp_fractional_scale_manager_v1>(
registry, id, &wp_fractional_scale_manager_v1_interface, 1);
display->SetFractionalScaleManager(manager);
+ } else if (iface.EqualsLiteral("org_kde_kwin_appmenu_manager")) {
+ auto* manager = WaylandRegistryBind<org_kde_kwin_appmenu_manager>(
+ registry, id, &org_kde_kwin_appmenu_manager_interface, 1);
+ display->SetAppMenuManager(manager);
} else if (iface.EqualsLiteral("gtk_primary_selection_device_manager") ||
iface.EqualsLiteral("zwp_primary_selection_device_manager_v1")) {
display->EnablePrimarySelection();
--- a/widget/gtk/nsWaylandDisplay.h
+++ b/widget/gtk/nsWaylandDisplay.h
@@ -14,6 +14,7 @@
#include "mozilla/widget/gbm.h"
#include "mozilla/widget/fractional-scale-v1-client-protocol.h"
#include "mozilla/widget/idle-inhibit-unstable-v1-client-protocol.h"
+#include "mozilla/widget/kwin-appmenu-v1-client-protocol.h"
#include "mozilla/widget/relative-pointer-unstable-v1-client-protocol.h"
#include "mozilla/widget/pointer-constraints-unstable-v1-client-protocol.h"
#include "mozilla/widget/linux-dmabuf-unstable-v1-client-protocol.h"
@@ -52,6 +53,7 @@
wp_fractional_scale_manager_v1* GetFractionalScaleManager() {
return mFractionalScaleManager;
}
+ org_kde_kwin_appmenu_manager* GetAppMenuManager() { return mAppMenuManager; }
bool IsPrimarySelectionEnabled() { return mIsPrimarySelectionEnabled; }
void SetShm(wl_shm* aShm);
@@ -68,6 +70,9 @@
void SetFractionalScaleManager(wp_fractional_scale_manager_v1* aManager) {
mFractionalScaleManager = aManager;
}
+ void SetAppMenuManager(org_kde_kwin_appmenu_manager* aManager) {
+ mAppMenuManager = aManager;
+ }
void EnablePrimarySelection() { mIsPrimarySelectionEnabled = true; }
~nsWaylandDisplay();
@@ -86,6 +91,7 @@
zwp_linux_dmabuf_v1* mDmabuf = nullptr;
xdg_activation_v1* mXdgActivation = nullptr;
wp_fractional_scale_manager_v1* mFractionalScaleManager = nullptr;
+ org_kde_kwin_appmenu_manager* mAppMenuManager = nullptr;
bool mExplicitSync = false;
bool mIsPrimarySelectionEnabled = false;
};
--- a/widget/gtk/NativeMenuGtk.h
+++ b/widget/gtk/NativeMenuGtk.h
@@ -12,6 +12,7 @@
#include "GRefPtr.h"
struct xdg_dbus_annotation_v1;
+struct org_kde_kwin_appmenu;
namespace mozilla {
@@ -81,6 +82,7 @@
RefPtr<GDBusProxy> mProxy;
# ifdef MOZ_WAYLAND
xdg_dbus_annotation_v1* mAnnotation = nullptr;
+ org_kde_kwin_appmenu* mAppMenu = nullptr;
# endif
};
--- a/widget/gtk/NativeMenuGtk.cpp
+++ b/widget/gtk/NativeMenuGtk.cpp
@@ -740,9 +740,6 @@
}
xdg_dbus_annotation_manager_v1* annotationManager =
display->GetXdgDbusAnnotationManager();
- if (NS_WARN_IF(!annotationManager)) {
- return;
- }
wl_surface* surface = gdk_wayland_window_get_wl_surface(gdkWin);
if (NS_WARN_IF(!surface)) {
@@ -755,12 +752,27 @@
return;
}
- // FIXME(emilio, bug 1883209): Nothing deletes this as of right now.
- mAnnotation = xdg_dbus_annotation_manager_v1_create_surface(
- annotationManager, "com.canonical.dbusmenu", surface);
-
- xdg_dbus_annotation_v1_set_address(mAnnotation, myServiceName,
- mObjectPath.get());
+ if (annotationManager) {
+ // FIXME(emilio, bug 1883209): Nothing deletes this as of right now.
+ mAnnotation = xdg_dbus_annotation_manager_v1_create_surface(
+ annotationManager, "com.canonical.dbusmenu", surface);
+
+ xdg_dbus_annotation_v1_set_address(mAnnotation, myServiceName,
+ mObjectPath.get());
+ } else {
+ // Set KDE appmenu
+ if (!mAppMenu) {
+ org_kde_kwin_appmenu_manager* manager = WaylandDisplayGet()->GetAppMenuManager();
+ if (!manager) { // not on KDE?
+ return;
+ }
+ mAppMenu = org_kde_kwin_appmenu_manager_create(manager, surface);
+ if (NS_WARN_IF(!mAppMenu)) { // create failed?
+ return;
+ }
+ }
+ org_kde_kwin_appmenu_set_address(mAppMenu, myServiceName, mObjectPath.get());
+ }
return;
}
# endif
@@ -820,6 +833,8 @@
DBusMenuBar::~DBusMenuBar() {
# ifdef MOZ_WAYLAND
MozClearPointer(mAnnotation, xdg_dbus_annotation_v1_destroy);
+ if (mAppMenu) org_kde_kwin_appmenu_release(mAppMenu);
+ MozClearPointer(mAppMenu, org_kde_kwin_appmenu_destroy);
# endif
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment