Instantly share code, notes, and snippets.
Created
June 25, 2024 20:24
-
Star
1
(1)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- /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