scratch-screen-share/maybe-screenshot.lisp

378 lines
22 KiB
Common Lisp

(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
;; #<DBUS/INTROSPECT::INTERFACE "org.freedesktop.portal.Screenshot">
(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!