From 29a5e56e6e0fdad161bc83064f4f04dbda7d8d59 Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Thu, 20 Oct 2022 00:28:01 +0800 Subject: [PATCH] Support wayland --- eaf.el | 26 +++++- .../eaf-wayland@emacs-eaf.org/extension.js | 83 +++++++++++++++++++ .../eaf-wayland@emacs-eaf.org/metadata.json | 10 +++ 3 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 gnome-shell/eaf-wayland@emacs-eaf.org/extension.js create mode 100644 gnome-shell/eaf-wayland@emacs-eaf.org/metadata.json diff --git a/eaf.el b/eaf.el index 5be164d58..54ee70340 100644 --- a/eaf.el +++ b/eaf.el @@ -1157,6 +1157,10 @@ kxsgtn/ignore_spurious_focus_events_for/") (let* ((window-allocation (eaf-get-window-allocation window)) (window-divider-right-padding (if window-divider-mode window-divider-default-right-width 0)) (window-divider-bottom-padding (if window-divider-mode window-divider-default-bottom-width 0)) + (titlebar-height (eaf--get-titlebar-height)) + (frame-coordinate (eaf--get-frame-coordinate)) + (frame-x (car frame-coordinate)) + (frame-y (cadr frame-coordinate)) (x (+ (eaf--buffer-x-position-adjust frame) (nth 0 window-allocation))) (y (+ (eaf--buffer-y-postion-adjust frame) (nth 1 window-allocation))) (w (nth 2 window-allocation)) @@ -1164,13 +1168,31 @@ kxsgtn/ignore_spurious_focus_events_for/") (push (format "%s:%s:%s:%s:%s:%s" eaf--buffer-id (eaf-get-emacs-xid frame) - x - y + (+ x frame-x) + (+ y titlebar-height frame-y) (- w window-divider-right-padding) (- h window-divider-bottom-padding)) view-infos))))))) (eaf-call-async "update_views" (mapconcat #'identity view-infos ",")))))) +(defun eaf--get-frame-coordinate () + (cond ((eaf-emacs-running-in-wayland-native) + (let* ((coordinate (mapcar #'string-to-number + (string-split + (dbus-call-method :session "org.gnome.Shell" "/org/eaf/wayland" "org.eaf.wayland" "get_emacs_window_coordinate" :timeout 1000) + ","))) + (frame-x (truncate (/ (car coordinate) (frame-scale-factor)))) + (frame-y (truncate (/ (cadr coordinate) (frame-scale-factor))))) + (list frame-x frame-y))) + (t + (list 0 0)))) + +(defun eaf--get-titlebar-height () + (let ((is-fullscreen-p (memq (frame-parameter nil 'fullscreen) '(fullscreen fullboth)))) + (if is-fullscreen-p + 0 + 32))) + (defun eaf--get-eaf-buffers () "A function that return a list of EAF buffers." (cl-remove-if-not diff --git a/gnome-shell/eaf-wayland@emacs-eaf.org/extension.js b/gnome-shell/eaf-wayland@emacs-eaf.org/extension.js new file mode 100644 index 000000000..945242c90 --- /dev/null +++ b/gnome-shell/eaf-wayland@emacs-eaf.org/extension.js @@ -0,0 +1,83 @@ +/* extension.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +/* exported init */ + +const { Gio } = imports.gi; + +const EAFWaylandInterface = ` + + + + + + + + + + +`; + +class wayland { + dbus; + + enable() { + this.dbus = Gio.DBusExportedObject.wrapJSObject( + EAFWaylandInterface, + this, + ); + this.dbus.export( + Gio.DBus.session, + '/org/eaf/wayland', + ); + } + + disable() { + this.dbus.unexport_from_connection( + Gio.DBus.session, + ); + this.dbus = undefined; + } + + get_windows() { + return global.get_window_actors() + .map(w => ({id: w.toString(), + ref: w, + title: w.get_meta_window().get_wm_class()})) + .filter(w => !w.title.includes('Gnome-shell')); + } + + get_active_window() { + return this.get_windows().slice(-1)[0].title + } + + get_emacs_window_coordinate() { + const match_windows = global.get_window_actors().filter(w => w.get_meta_window().get_wm_class() == "emacs") + if (match_windows[0] == undefined) { + return "0,0" + } else { + const emacs_window = match_windows[0] + const rect = emacs_window.get_meta_window().get_frame_rect() + return rect.x + "," + rect.y + } + } +} + +function init() { + return new wayland(); +} diff --git a/gnome-shell/eaf-wayland@emacs-eaf.org/metadata.json b/gnome-shell/eaf-wayland@emacs-eaf.org/metadata.json new file mode 100644 index 000000000..bbfbbbd00 --- /dev/null +++ b/gnome-shell/eaf-wayland@emacs-eaf.org/metadata.json @@ -0,0 +1,10 @@ +{ + "description": "Expose a D-Bus interface to help EAF running on Wayland", + "name": "EAF Waynland Extension", + "shell-version": [ + "42" + ], + "url": "https://github.com/emacs-eaf/emacs-application-framework", + "uuid": "eaf-wayland@emacs-eaf.org", + "version": 1 +}