(load (sb-ext:posix-getenv "ASDF")) (asdf:load-system 'dbus) (defpackage #:screenshotting (:use #:cl)) (in-package #:screenshotting) ;; let's try to initiate and get screenshot somehow ;; # (iolib/multiplex:with-event-base (event-base) (dbus:with-open-connection (connection event-base (dbus:session-server-addresses)) (dbus:authenticate (dbus:supported-authentication-mechanisms connection) connection) (dbus:hello connection) (let ((obj (dbus:make-object-from-introspection connection "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop"))) (dbus:list-interface-methods (dbus:object-interface "org.freedesktop.portal.Screenshot" obj))))) (defun start () (handler-case (dbus:with-open-bus (bus (dbus:session-server-addresses)) (format T "Bus connection name ~A~%" (dbus:bus-name bus))) (end-of-file () :disconnected-by-bus))) ;; https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Screenshot.html ;; Since version 0.9 of xdg-desktop-portal, the handle will be of the form ;;/org/freedesktop/portal/desktop/request/SENDER/TOKEN ;; so for me it would be (dbus:bus-name bus) and "param-i-ve-passed" ;; a question aboud argument with vararg array ;; https://github.com/death/dbus/issues/20 (defun call-screenshot () (handler-case (dbus:with-open-bus (bus (dbus:session-server-addresses)) (format T "Bus connection name ~A~%" (dbus:bus-name bus)) (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") (desktop "org.freedesktop.portal.Screenshot" "Screenshot" "" '(("handle_token" ((:string) "yayay"))))) (dbus:add-match bus :type :signal :interface "org.freedesktop.portal.Request" :destination (dbus:bus-name bus)) (DBUS:publish-objects bus)))) ;; checking params for signal with ;; (dbus:sigexp "ua{sv}") ;; as string from here https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Request.html#request ;; wowy, i get the link with my handle ;; "/org/freedesktop/portal/desktop/request/1_87/yayay" ;; and now the result should be signalled on the Reply object at that path ;; lot's of stuff in dbus-monitor: ;; method call time=1719909623.911588 sender=:1.89 -> destination=org.freedesktop.portal.Desktop serial=3 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.portal.Screenshot; member=Screenshot ;; string "" ;; array [ ;; dict entry( ;; string "handle_token" ;; variant string "yayay" ;; ) ;; ] ;; method call time=1719909623.911612 sender=:1.23 -> destination=org.freedesktop.DBus serial=212 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionUnixProcessID ;; string ":1.89" ;; method return time=1719909623.911618 sender=org.freedesktop.DBus -> destination=:1.23 serial=152 reply_serial=212 ;; uint32 93638 ;; method call time=1719909623.911624 sender=:1.23 -> destination=org.freedesktop.DBus serial=213 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type='signal',sender='org.freedesktop.impl.portal.desktop.gnome',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/freedesktop/portal/desktop/request/1_89/yayay',arg0='org.freedesktop.impl.portal.Request'" ;; method return time=1719909623.911631 sender=org.freedesktop.DBus -> destination=:1.23 serial=153 reply_serial=213 ;; method call time=1719909623.911635 sender=:1.23 -> destination=org.freedesktop.DBus serial=214 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type='signal',sender='org.freedesktop.impl.portal.desktop.gnome',interface='org.freedesktop.impl.portal.Request',path='/org/freedesktop/portal/desktop/request/1_89/yayay'" ;; method return time=1719909623.911641 sender=org.freedesktop.DBus -> destination=:1.23 serial=154 reply_serial=214 ;; method call time=1719909623.911644 sender=:1.23 -> destination=org.freedesktop.DBus serial=215 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=StartServiceByName ;; string "org.freedesktop.impl.portal.desktop.gnome" ;; uint32 0 ;; method return time=1719909623.911651 sender=org.freedesktop.DBus -> destination=:1.23 serial=155 reply_serial=215 ;; uint32 2 ;; method call time=1719909623.911657 sender=:1.23 -> destination=org.freedesktop.DBus serial=216 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner ;; string "org.freedesktop.impl.portal.desktop.gnome" ;; method return time=1719909623.911662 sender=org.freedesktop.DBus -> destination=:1.23 serial=156 reply_serial=216 ;; string ":1.28" ;; method call time=1719909623.911668 sender=:1.23 -> destination=:1.28 serial=217 path=/org/freedesktop/portal/desktop/request/1_89/yayay; interface=org.freedesktop.DBus.Properties; member=GetAll ;; string "org.freedesktop.impl.portal.Request" ;; error time=1719909623.911674 sender=:1.28 -> destination=:1.23 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=217 ;; string "Object does not exist at path “/org/freedesktop/portal/desktop/request/1_89/yayay”" ;; method call time=1719909623.911680 sender=:1.23 -> destination=:1.28 serial=218 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.impl.portal.Screenshot; member=Screenshot ;; object path "/org/freedesktop/portal/desktop/request/1_89/yayay" ;; string "" ;; string "" ;; array [ ;; ] ;; method return time=1719909623.911693 sender=:1.23 -> destination=:1.89 serial=219 reply_serial=3 ;; object path "/org/freedesktop/portal/desktop/request/1_89/yayay" ;; signal time=1719909623.911699 sender=org.freedesktop.DBus -> destination=:1.89 serial=5 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost ;; string ":1.89" ;; signal time=1719909623.911705 sender=org.freedesktop.DBus -> destination=(null destination) serial=123 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged ;; string ":1.89" ;; string ":1.89" ;; string "" ;; method call time=1719909623.911714 sender=:1.23 -> destination=:1.28 serial=220 path=/org/freedesktop/portal/desktop/request/1_89/yayay; interface=org.freedesktop.impl.portal.Request; member=Close ;; error time=1719909623.911717 sender=:1.28 -> destination=:1.23 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=220 ;; string "Object does not exist at path “/org/freedesktop/portal/desktop/request/1_89/yayay”" ;; does this mean that I should be the one creating the response object? ;; well, now maybe i will be able to figure out more in the flameshot repo ;; https://github.com/flameshot-org/flameshot/blob/c1dac52231024174faa68a29577129ebca125dff/src/utils/screengrabber.cpp#L59 ;; or, well, the Claude writes that maybe connection is closed prematurely because nobody is listening? (cl-ppcre:regex-replace "\\." ":1.241" "_" :start 1) (defun call-screenshot () (handler-case (dbus:with-open-bus (bus (dbus:session-server-addresses)) (let* ((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1)) (request-name "yayay") (resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" requester-name "/" request-name))) (dbus:define-dbus-object request-object (:path resp-path)) (dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) (:interface "org.freedesktop.portal.Request") (format t "Got response ~A with results ~A~%" id results)) (format T "Will try to listen on ~A~%" resp-path) (format T "Bus connection name ~A~%" (dbus:bus-name bus)) (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") (desktop "org.freedesktop.portal.Screenshot" "Screenshot" "" '(("handle_token" ((:string) "yayay"))))) (dbus:add-match bus :type :signal :interface "org.freedesktop.portal.Request") (dbus:publish-objects bus))))) ;; with new code inserted about listening on request.response ;; method call time=1720082195.600449 sender=:1.207 -> destination=org.freedesktop.portal.Desktop serial=3 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.portal.Screenshot; member=Screenshot ;; string "" ;; array [ ;; dict entry( ;; string "handle_token" ;; variant string "yayay" ;; ) ;; ] ;; method call time=1720082195.600630 sender=:1.23 -> destination=org.freedesktop.DBus serial=1869 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionUnixProcessID ;; string ":1.207" ;; method return time=1720082195.600635 sender=org.freedesktop.DBus -> destination=:1.23 serial=212 reply_serial=1869 ;; uint32 93638 ;; method call time=1720082195.600871 sender=:1.23 -> destination=org.freedesktop.DBus serial=1870 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type='signal',sender='org.freedesktop.impl.portal.desktop.gnome',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/freedesktop/portal/desktop/request/1_207/yayay',arg0='org.freedesktop.impl.portal.Request'" ;; method return time=1720082195.600875 sender=org.freedesktop.DBus -> destination=:1.23 serial=213 reply_serial=1870 ;; method call time=1720082195.600883 sender=:1.23 -> destination=org.freedesktop.DBus serial=1871 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type='signal',sender='org.freedesktop.impl.portal.desktop.gnome',interface='org.freedesktop.impl.portal.Request',path='/org/freedesktop/portal/desktop/request/1_207/yayay'" ;; method return time=1720082195.600887 sender=org.freedesktop.DBus -> destination=:1.23 serial=214 reply_serial=1871 ;; method call time=1720082195.600902 sender=:1.23 -> destination=org.freedesktop.DBus serial=1872 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=StartServiceByName ;; string "org.freedesktop.impl.portal.desktop.gnome" ;; uint32 0 ;; method return time=1720082195.600907 sender=org.freedesktop.DBus -> destination=:1.23 serial=215 reply_serial=1872 ;; uint32 2 ;; method call time=1720082195.600959 sender=:1.23 -> destination=org.freedesktop.DBus serial=1873 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner ;; string "org.freedesktop.impl.portal.desktop.gnome" ;; method return time=1720082195.600963 sender=org.freedesktop.DBus -> destination=:1.23 serial=216 reply_serial=1873 ;; string ":1.28" ;; method call time=1720082195.601013 sender=:1.23 -> destination=:1.28 serial=1874 path=/org/freedesktop/portal/desktop/request/1_207/yayay; interface=org.freedesktop.DBus.Properties; member=GetAll ;; string "org.freedesktop.impl.portal.Request" ;; error time=1720082195.601138 sender=:1.28 -> destination=:1.23 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=1874 ;; string "Object does not exist at path “/org/freedesktop/portal/desktop/request/1_207/yayay”" ;; method call time=1720082195.601215 sender=:1.23 -> destination=:1.28 serial=1875 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.impl.portal.Screenshot; member=Screenshot ;; object path "/org/freedesktop/portal/desktop/request/1_207/yayay" ;; string "" ;; string "" ;; array [ ;; ] ;; method return time=1720082195.601235 sender=:1.23 -> destination=:1.207 serial=1876 reply_serial=3 ;; object path "/org/freedesktop/portal/desktop/request/1_207/yayay" ;; method call time=1720082195.601435 sender=:1.207 -> destination=org.freedesktop.DBus serial=4 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type=signal,interface=org.freedesktop.portal.Request,destination=:1.207" ;; method return time=1720082195.604833 sender=org.freedesktop.DBus -> destination=:1.207 serial=3 reply_serial=4 ;; signal time=1720082198.479133 sender=:1.192 -> destination=(null destination) serial=221 path=/org/gnome/Terminal/window/2; interface=org.gtk.Actions; member=Changed ;; array [ ;; ] ;; array [ ;; dict entry( ;; string "copy" ;; boolean true ;; ) ;; ] ;; array [ ;; ] ;; array [ ;; ] ;; trying suggestion on not creating an object ourselves? (defun call-screenshot-register-request () (handler-case (dbus:with-open-bus (bus (dbus:session-server-addresses)) (let* ((bus-name (dbus:bus-name bus)) (request-name "yayay")) (dbus:define-dbus-object root-object (:path "/")) (dbus:define-dbus-signal-handler (root-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) (:interface "org.freedesktop.portal.Request") (format t "Got response ~A with results ~A~%" id results)) (format T "Bus connection name ~A~%" (dbus:bus-name bus)) (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") (desktop "org.freedesktop.portal.Screenshot" "Screenshot" "" '(("handle_token" ((:string) "yayay"))))) (dbus:add-match bus :type :signal :interface "org.freedesktop.portal.Request") (dbus:publish-objects bus))))) ;; method call time=1720270194.734644 sender=:1.95 -> destination=org.freedesktop.portal.Desktop serial=3 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.portal.Screenshot; member=Screenshot ;; string "" ;; array [ ;; dict entry( ;; string "handle_token" ;; variant string "yayay" ;; ) ;; ] ;; method call time=1720270194.734664 sender=:1.25 -> destination=org.freedesktop.DBus serial=239 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionUnixProcessID ;; string ":1.95" ;; method return time=1720270194.734669 sender=org.freedesktop.DBus -> destination=:1.25 serial=169 reply_serial=239 ;; uint32 94649 ;; method call time=1720270194.734674 sender=:1.25 -> destination=org.freedesktop.DBus serial=240 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type='signal',sender='org.freedesktop.impl.portal.desktop.gnome',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='/org/freedesktop/portal/desktop/request/1_95/yayay',arg0='org.freedesktop.impl.portal.Request'" ;; method return time=1720270194.734679 sender=org.freedesktop.DBus -> destination=:1.25 serial=170 reply_serial=240 ;; method call time=1720270194.734682 sender=:1.25 -> destination=org.freedesktop.DBus serial=241 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type='signal',sender='org.freedesktop.impl.portal.desktop.gnome',interface='org.freedesktop.impl.portal.Request',path='/org/freedesktop/portal/desktop/request/1_95/yayay'" ;; method return time=1720270194.734688 sender=org.freedesktop.DBus -> destination=:1.25 serial=171 reply_serial=241 ;; method call time=1720270194.734691 sender=:1.25 -> destination=org.freedesktop.DBus serial=242 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=StartServiceByName ;; string "org.freedesktop.impl.portal.desktop.gnome" ;; uint32 0 ;; method return time=1720270194.734698 sender=org.freedesktop.DBus -> destination=:1.25 serial=172 reply_serial=242 ;; uint32 2 ;; method call time=1720270194.734702 sender=:1.25 -> destination=org.freedesktop.DBus serial=243 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner ;; string "org.freedesktop.impl.portal.desktop.gnome" ;; method return time=1720270194.734707 sender=org.freedesktop.DBus -> destination=:1.25 serial=173 reply_serial=243 ;; string ":1.30" ;; method call time=1720270194.734712 sender=:1.25 -> destination=:1.30 serial=244 path=/org/freedesktop/portal/desktop/request/1_95/yayay; interface=org.freedesktop.DBus.Properties; member=GetAll ;; string "org.freedesktop.impl.portal.Request" ;; error time=1720270194.734718 sender=:1.30 -> destination=:1.25 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=244 ;; string "Object does not exist at path “/org/freedesktop/portal/desktop/request/1_95/yayay”" ;; method call time=1720270194.734723 sender=:1.25 -> destination=:1.30 serial=245 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.impl.portal.Screenshot; member=Screenshot ;; object path "/org/freedesktop/portal/desktop/request/1_95/yayay" ;; string "" ;; string "" ;; array [ ;; ] ;; method return time=1720270194.734736 sender=:1.25 -> destination=:1.95 serial=246 reply_serial=3 ;; object path "/org/freedesktop/portal/desktop/request/1_95/yayay" ;; method call time=1720270194.734741 sender=:1.95 -> destination=org.freedesktop.DBus serial=4 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch ;; string "type=signal,interface=org.freedesktop.portal.Request" ;; method return time=1720270194.754781 sender=org.freedesktop.DBus -> destination=:1.95 serial=3 reply_serial=4 ;; well, it seems that still same Object does not exist ;; so. oh. it's 1_95, so what. ;; i'm not subscribing to same thing, right? ;; let's try to chagne in place ;; um. what. what if i manually send to Request sinal? ;; and these changes they are messy, would be better to use commits (defun call-screenshot () (handler-case (dbus:with-open-bus (bus (dbus:session-server-addresses)) (let* ((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1)) (request-name "yayay") (resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" requester-name "/" request-name))) (dbus:define-dbus-object request-object (:path resp-path)) (dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) (:interface "org.freedesktop.portal.Request") (format t "Got response ~A with results ~A~%" id results)) (format T "Will try to listen on ~A~%" resp-path) (format T "Bus connection name ~A~%" (dbus:bus-name bus)) ;; (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") ;; (desktop "org.freedesktop.portal.Screenshot" "Screenshot" ;; "" ;; '(("handle_token" ((:string) "yayay"))))) (dbus:add-match bus :type :signal :interface "org.freedesktop.portal.Request") (dbus:publish-objects bus))))) ;; ok, dbus-send can't add a{sv} because dict:string:variant is not allowed ;; variant is a container and nesting is not supported by the tool ;; let's try again on the real method call? (defun call-screenshot () (handler-case (dbus:with-open-bus (bus (dbus:session-server-addresses)) (let* ((requester-name (cl-ppcre:regex-replace "\\." (dbus:bus-name bus) "_" :start 1)) (request-name "yayay") (resp-path (concatenate 'string "/org/freedesktop/portal/desktop/request/" requester-name "/" request-name))) (dbus:define-dbus-object request-object (:path resp-path)) (dbus:define-dbus-signal-handler (request-object response) ((id :uint32) (results (:ARRAY (:DICT-ENTRY :STRING :VARIANT)))) (:interface "org.freedesktop.portal.Request") (format t "Got response ~A with results ~A~%" id results)) (format T "Will try to listen on ~A~%" resp-path) (format T "Bus connection name ~A~%" (dbus:bus-name bus)) (dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop") (desktop "org.freedesktop.portal.Screenshot" "Screenshot" "" '(("handle_token" ((:string) "yayay"))))) (dbus:add-match bus :type :signal :interface "org.freedesktop.portal.Request") (dbus:publish-objects bus))))) ;;; uhm, let's try another method that should more certainly work ;; gdbus call --session --dest org.freedesktop.portal.Desktop --object-path /org/freedesktop/portal/desktop --method org.freedesktop.portal.FileChooser.OpenFile "" "Choose a file" '{}' ;; and when trying with a screenshot ;; $ gdbus call --session --dest org.freedesktop.portal.Desktop --object-path /org/freedesktop/portal/desktop --method org.freedesktop.portal.Screenshot.Screenshot "" '{}' ;; this returns the path ;; wow ;; this has info ;; systemctl --user status xdg-desktop-portal-gnome.service ;; Jul 06 15:14:28 LLF33A87M xdg-desktop-portal-gnome[3770]: Failed to get screenshot: Cannot invoke method; proxy is for the well-known name org.gnome.Shell.Screenshot without an owner, and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag ;; and. if i want to be able to get screenshots i'll need another backend ;; https://wiki.archlinux.org/title/XDG_Desktop_Portal ;; so. not on xmonad or pure X11 ;; i could try wayland and another tiling manager, you know ;; but i guess first restart into gnome session and try to call gdbus from there ;; List of backends and interfaces ;; The following table lists all backends available and their support for certain common interfaces. ;; Backend File chooser Screenshot and screen cast ;; xdg-desktop-portal-dde Yes Yes, on Deepin Desktop Environment ;; xdg-desktop-portal-gtk Yes No ;; xdg-desktop-portal-gnome Yes Yes, on GNOME ;; xdg-desktop-portal-kde Yes Yes, on KDE ;; xdg-desktop-portal-hyprland1 No Yes, on wlroots ;; xdg-desktop-portal-lxqt Yes No ;; xdg-desktop-portal-wlr No Yes, on wlroots ;; xdg-desktop-portal-xapp No Yes, on Cinnamon ;; xdg-desktop-portal-liri-gitAUR Yes Yes, on Liri ;; xdg-desktop-portal-shanaAUR Yes2 No ;; xdg-desktop-portal-tdAUR Yes No ;; xdg-desktop-portal-termfilechooser-gitAUR Yes3 No ;; yep, looks like this does work on gnome, so, yeah. ;; well, let's try another window manager? one on wlroots maybe just hyprland ;; or qtile which should also use wlroots, but do i need this hackability? ;; i don't think i'm using it for much, so hyprland? ;; because i don't even really want to use python for hacking ;; or, alternatively i guess i could try to install on Ubuntu ;; yeah, seems huh. will probably not launch through just home-manager? ;; or maybe it exactly will, just pull it's own wayland and stuff ;; https://github.com/nix-community/home-manager/issues/1167 maybe things won't work ;; i tried to install sway just on ubuntu ;; and thing works somewhat, but screenshots are blocked ;; not sure what to do about that. ;; i could continue working on gnome for now ;; OH, whoah. this faq https://github.com/emersion/xdg-desktop-portal-wlr ;; has link to python3 snippet ;; https://gitlab.gnome.org/-/snippets/19 ;; and that starts the screen cast!