emacs-eaf / emacs-application-framework

EAF, an extensible framework that revolutionizes the graphical capabilities of Emacs
GNU General Public License v3.0
3.05k stars 230 forks source link

Native wayland support for swaywm #1044

Closed ATNewHope closed 1 year ago

ATNewHope commented 1 year ago

See #1043 .

To resolve the problem above, I've tried a lot and finally succeeded in using a bash script to get the focsed emacs' window coordinates and size. https://github.com/ATNewHope/swaymsg-treefetch

Since I'm a newbie to linux and not a programmer, this is my current best. Any help on reaching the goal from this point is highly apprieciated.

manateelazycat commented 1 year ago

Well done.

You need write script to get active window and then add branch at here: https://github.com/emacs-eaf/emacs-application-framework/blob/546ada067feb280bf34deb63beaddd3e0cc72276/eaf.el#L1038

Then write script get emacs window coordinate, then add branch at here: https://github.com/emacs-eaf/emacs-application-framework/blob/546ada067feb280bf34deb63beaddd3e0cc72276/eaf.el#L1155

And you need write an elisp function to check enviroment is sway wm.

I believe EAF will works after you finish above three steps.

ATNewHope commented 1 year ago

Thanks for the help.

You need write script to get active window and then add branch at here:

What does "get active window" mean? My script finds all windows with provided app_id (i.e. "emacs"), and prefer the focused (activated) one if exists. Is this enough to achieve the goal?

manateelazycat commented 1 year ago

Because we can't use XReparent technology in Wayland native, so EAF as topmost window that above Emacs.

So we need know active window is whether Emacs window? Then eaf--topmost-focus-change will know when focus in EAF and when focus out EAF.

The purpose of "get active window" is make EAF have input focus correctly.

I don't know your script since I don't use Sway, you need test it yourself.

ATNewHope commented 1 year ago

So, if emacs is focused, the branch to be at after the first '(t' shoud return a string value "emacs". Isn't it? Or a boolean value "true"?

manateelazycat commented 1 year ago

So, if emacs is focused, the branch to be at after the first '(t' shoud return a string value "emacs". Isn't it? Or a boolean value "true"?

Return string, "emacs", not boolean value.

ATNewHope commented 1 year ago

Done with bash part. https://github.com/ATNewHope/swaymsg-treefetch See the "Examples" part.

For the last step, I guess I must learn elisp first to achive that.

manateelazycat commented 1 year ago

Done with bash part. https://github.com/ATNewHope/swaymsg-treefetch See the "Examples" part.

For the last step, I guess I must learn elisp first to achive that.

Sway have some environment variable we can check?

ATNewHope commented 1 year ago

Sway have some environment variable we can check?

Yes, if configured properly, then

XDG_CURRENT_DESKTOP=sway
XDG_SESSION_DESKTOP=sway
manateelazycat commented 1 year ago

Then last step should write (string-equal (getenv "XDG_CURRENT_DESKTOP") "sway") for test whether in Sway WM

manateelazycat commented 1 year ago

You need test those three steps in your Sway, PR are welcome.

ATNewHope commented 1 year ago

Tried to understand the code, then for the 2nd step,

(defun eaf--get-frame-coordinate ()
  "We need fetch Emacs coordinate to adjust coordinate of EAF if it running on system not support cross-process reparent technology.

Such as, wayland native, macOS etc."
  (cond ((eaf-emacs-running-in-wayland-native)
         (require 'dbus)
         (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)
                                     ",")))
                ;; HiDPI need except by `frame-scale-factor'.
                (frame-x (truncate (/ (car coordinate) (frame-scale-factor))))
                (frame-y (truncate (/ (cadr coordinate) (frame-scale-factor)))))
           (list frame-x frame-y)))
    ((string-equal (getenv "XDG_CURRENT_DESKTOP") "sway")
     (list (shell-command-to-string "bash /hub/swaymsg-treefetch/swaymsg-rectfetcher.sh emacs")))
        (t
         (list 0 0))))
manateelazycat commented 1 year ago

https://github.com/emacs-eaf/emacs-application-framework/blob/546ada067feb280bf34deb63beaddd3e0cc72276/eaf.el#L284

ATNewHope commented 1 year ago

Open PDF viewer, stucked and no page rendered.

Seems to be a qt wayland problem.

No related error in message buffer. eaf buffer:

Process eaf aborted (core dumped) Failed to create wl_display (No such file or directory) qt.qpa.plugin: Could not load the Qt platform plugin "wayland" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vkkhrdisplay, vnc, wayland-egl, wayland, xcb.

Interestingly, it's still good about 12 hours ago, with minor glitch but do work with my keyboard and mouse, and rendered all the pages. I didn't modify the eaf.el at that time.

Considering that I'm using Emacs 30.0.50 for pgtk support, this unstable situation is reasonable. Maybe Emacs 29 stable will merge in pgtk support, so that the goal here will be more easy to achived.

Also, I should do more research on QT problem.

ATNewHope commented 1 year ago
(defun eaf--get-frame-coordinate ()
  "We need fetch Emacs coordinate to adjust coordinate of EAF if it running on system not support cross-process reparent technology.

Such as, wayland native, macOS etc."
  (cond ((eaf-emacs-running-in-wayland-native)
         (require 'dbus)
         (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)
                                     ",")))
                ;; HiDPI need except by `frame-scale-factor'.
                (frame-x (truncate (/ (car coordinate) (frame-scale-factor))))
                (frame-y (truncate (/ (cadr coordinate) (frame-scale-factor)))))
           (list frame-x frame-y)))
; Added part begin
    ((string-equal (getenv "XDG_CURRENT_DESKTOP") "sway")
     (let ((default-directory eaf-build-dir))
;      (list (shell-command-to-string "bash ./swaymsg-treefetch/swaymsg-rectfetcher-x.sh emacs") (shell-command-to-string "bash ./swaymsg-treefetch/swaymsg-rectfetcher-y.sh emacs"))))
       (list (shell-command-to-string "bash ./swaymsg-treefetch/swaymsg-rectfetcher.sh emacs"))))
; Added part end
        (t
         (list 0 0))))

Considering that swaymsg-rectfetcher will return a "x y" together, e.g.

$swaymsg-rectfetcher.sh emacs
1020 760

Please tell me, is the code after "list" correct? Or return separately as the comment line.

Also, I had to point out that the coordinate the script returns is the point AT RIGHT TOP CORNER. Is this fine? (Or I should use width and height to figure out the "x y" of another corner)

manateelazycat commented 1 year ago

Use (string-split (shell-command-to-string "bash ./swaymsg-treefetch/swaymsg-rectfetcher.sh emacs")) instead

You need return point at LEFT TOP CORNER of emacs window.

ATNewHope commented 1 year ago

你先换个gnome3 xwayland或者kde的环境测试一下,确保pyqt没问题。

你的问题看起来像系统升级后pyqt挂了。

补丁还是要测试一下再提交吧。

我这边暂时没条件做这个测试,主要是磁盘空间比较吃紧。这个issue先关了吧,日后再说。