let's do ugly versioning in my playground

This commit is contained in:
efim 2024-07-07 17:31:51 +00:00
commit 70de7c4491
11 changed files with 1113 additions and 0 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/*~
/.direnv/

60
flake.lock Normal file
View File

@ -0,0 +1,60 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1719597372,
"narHash": "sha256-SpZKwy6sjgH00xiYmfjVAX+JaNkPQ2Q/BrEhNtWJvH4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "dd66e39ec4c7252fab7e6f8fd57b5ab2a3c7d63c",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

33
flake.nix Normal file
View File

@ -0,0 +1,33 @@
{
description = "common lisp dbus playground";
inputs.nixpkgs.url = "github:nixos/nixpkgs";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
# https://nixos.org/manual/nixpkgs/stable/#lisp-overriding-package-attributes
# getting version with automatic introspection mixin
dbus' = pkgs.sbcl.pkgs.dbus.overrideLispAttrs (oldAttrs: rec {
version = "1.4";
src = pkgs.fetchFromGitHub {
owner = "death";
repo = "dbus";
rev = "master";
hash = "sha256-xbg3tPYfRNGJo+9F/58w2bDeZqV33Z871+ClSg4ACPk=";
};
});
sbcl' = pkgs.sbcl.withPackages (ps: [ ps.alexandria dbus' ]);
in
{
devShells.default = pkgs.mkShell {
buildInputs = [
sbcl'
];
};
}
);
# see https://serokell.io/blog/practical-nix-flakes
}

30
listen-to-responses.lisp Normal file
View File

@ -0,0 +1,30 @@
;;;; +----------------------------------------------------------------+
;;;; | DBUS |
;;;; +----------------------------------------------------------------+
(load (sb-ext:posix-getenv "ASDF"))
(asdf:load-system 'dbus)
(defpackage #:listening-response
(:use #:cl #:dbus)
(:export #:publish-example))
(in-package #:listening-response)
(define-dbus-object root
(:path "/"))
(define-dbus-signal-handler (root response) ()
(:interface "org.freedesktop.portal.Request")
(format t "Got signal with arg ~S~%" "yup")
(force-output))
(defun listen-for-responses ()
(handler-case
(with-open-bus (bus (session-server-addresses))
(format t "Bus connection name: ~A~%" (bus-name bus))
(dbus:add-match bus :type :signal :interface "org.freedesktop.portal.Request")
(publish-objects bus))
(end-of-file ()
:disconnected-by-bus))) ; org.freedesktop.portal.Request
;; yep, works with
;; dbus-send --session --type=signal / org.freedesktop.portal.Request.Response
;; again, will need to register object on the expected response path

119
maybe-screencast.lisp Normal file
View File

@ -0,0 +1,119 @@
(load (sb-ext:posix-getenv "ASDF"))
(asdf:load-system 'dbus)
(defpackage #:screencasting (:use #:cl))
(in-package #:screencasting)
;; https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.ScreenCast.html
(defconstant +screen-cast-interface+ "org.freedesktop.portal.ScreenCast")
(defconstant +request-interface+ "org.freedesktop.portal.ScreenCast")
;; i'm not sure how to do interactive calls,
;; since maybe i need to "publish objects"
;; and that means the callbacks are set in stone?
;; i guess i could try to do a Notification call in the callback on screenshot request?
(with-open-bus (bus (session-server-addresses))
(with-introspected-object (notification bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
(notification "org.freedesktop.Notifications" "Notify"
"Test" 0 "" "Test" "This is a test; I repeat, this is a test." '() '() -1)
))
(defun send-notification (bus message)
(dbus:with-introspected-object (notification bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
(notification "org.freedesktop.Notifications" "Notify"
"Test" 0 "" "Test" (or message "This is a test; I repeat, this is a test.") '() '() -1)))
;; i guess i could pass both bus and
(defun call-screencast ()
(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 +request-interface+)
(format t "Got response ~S with results ~S~%" id results)
(send-notification bus "yayaya from the first response"))
(format T "Will try to listen on ~A~%" resp-path)
(format T "Bus connection name ~A~%" (dbus:bus-name bus))
(dbus:add-match bus :type :signal
:interface "org.freedesktop.portal.Request")
(dbus:with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
(desktop +screen-cast-interface+ "CreateSession"
'(("handle_token" ((:string) "yayay"))
("session_handle_token" ((:string) "hohoyyy")))))
(dbus:publish-objects bus)))
(end-of-file ()
:disconnected-by-bus)))
;; let's then try to move macroses that define 'request' to outside?
;; they would take bus, create expected request-response listener
(alexandria:with-gensyms (lala)
(format nil "i-got-gensym-~S" lala))
;; well this notification library has interactive "register callback"
;; for multiple callbacks on Notification signals
;; https://github.com/Lautaro-Garcia/cl-notify/blob/main/src/signals.lisp
;; basicly loop starts and one signal-handler that calls all currently registered
;; i guess for my case i'll want separate with-open-bus?
;; how would i then exit the publish-objects loop?
;; am i really expected to exit it?
;; alright, let's try to start publish objects and after that registering stuff
;; to do the call?
(defun do-request (bus)
(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)
(send-notification bus "yayaya from the first response"))
(format T "Will try to make a call for ~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)))
(defvar *running-bus*)
(do-request *running-bus*)
(defun run-bus ()
(handler-case
(dbus:with-open-bus (bus (dbus:session-server-addresses))
(format T "Bus connection name ~A~%" (dbus:bus-name bus))
(setq *running-bus* bus)
(dbus:publish-objects bus))
(end-of-file ()
:disconnected-by-bus)))
;; well, i suppose i would need to open multiple connections?
;; let's do something like this https://github.com/Lautaro-Garcia/cl-notify/blob/main/src/dbus-protocol.lisp#L27
;; (defmacro with-dbus-method-inovaction ((result-var method &rest args) &body body)
;; (alexandria:with-gensyms (bus notifications-object)
;; `(dbus:with-open-bus (,bus (dbus:session-server-addresses))
;; (dbus:with-introspected-object (,notifications-object ,bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
;; (let ((,result-var (,notifications-object "org.freedesktop.Notifications" ,method ,@args)))
;; ,@body)))))
;; but. this supposes result-var being a resulting value
;; and i'd want to what? pass in a callback to register?

377
maybe-screenshot.lisp Normal file
View File

@ -0,0 +1,377 @@
(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!

31
maybe-signals.lisp Normal file
View File

@ -0,0 +1,31 @@
(defpackage #:notification-example
(:use #:cl #:dbus)
(:export #:listen-for-notifications))
(in-package #:notification-example)
(define-dbus-object root-object
(:path "/"))
(define-dbus-signal-handler (root-object on-notification-closed) ((id :uint32) (reason :uint32))
(:interface "org.freedesktop.Notifications")
(:name "NotificationClosed")
(format t "Notification ~A closed for reason ~A~%" id reason))
(define-dbus-signal-handler (root-object on-action-invoked) ((id :uint32) (action-key :string))
(:interface "org.freedesktop.Notifications")
(:name "ActionInvoked")
(format t "Action ~A invoked on notification ~A~%" action-key id))
(defun listen-for-notifications ()
(with-open-bus (bus (session-server-addresses))
(format t "Bus connection name: ~A~%" (bus-name bus))
(add-match bus :type :signal
:interface "org.freedesktop.Notifications"
:member "NotificationClosed")
(add-match bus :type :signal
:interface "org.freedesktop.Notifications"
:member "ActionInvoked")
(publish-objects bus)
(format t "Listening for notification signals...~%")
(loop (sleep 1)
(format t ".")
(force-output))))

33
notes.org Normal file
View File

@ -0,0 +1,33 @@
* [2024-06-28 Fri]
** well, i'm setting up sbcl and sly?
because i imagine using Common Lisp for my attempt at building screen
sharing for the XR glasses
for the cool runtime access, right?
** well, just flake shell and (use-package sly) is enough
for .lisp files to get stuff
yes, i'm still using C-M-f and stuff to move around sexps but things are fine
so, what's next?
well, this is nice high level description
dbus
https://www.freedesktop.org/wiki/Software/dbus/
and here's something to start usage
https://blog.macrolet.net/posts/DBus-and-PolicyKit-from-Common-Lisp.html
from https://github.com/death/dbus
and even lots of examples, but i think i will need a big book on Common Lisp to learn new things?
* [2024-06-29 Sat]
** going through the dbus guide, sounds neat
https://develop.kde.org/docs/features/d-bus/introduction_to_dbus/
that qdbus and qdbus-viewer are in
#+begin_src bash
$ nix shell nixpkgs#kdePackages.qttools
#+end_src
** now let's read about calling methods
* the receiving of the signals

50
notify-with-listen.lisp Normal file
View File

@ -0,0 +1,50 @@
;;;; +----------------------------------------------------------------+
;;;; | DBUS |
;;;; +----------------------------------------------------------------+
(load (sb-ext:posix-getenv "ASDF"))
(asdf:load-system 'dbus)
(defpackage #:publish-example
(:use #:cl #:dbus)
(:export #:publish-example))
(in-package #:publish-example)
(define-dbus-object root
(:path "/"))
(define-dbus-object my-service
(:path "/org/adeht/MyService")
(:parent root))
(define-dbus-method (my-service my-method) ((s1 :string) (s2 :string)) (:string)
(:interface "org.adeht.MyService")
(format t "will process call for ~S and ~S~%" s1 s2)
(force-output)
(concatenate 'string "updated" s1 s2))
(define-dbus-signal-handler (my-service on-signal) ()
(:interface "org.adeht.MyService")
(format t "Got signal with arg ~S~%" "hoh")
(force-output))
(define-dbus-signal-handler (root on-signal) ((s :string))
(:interface "org.adeht.MyService")
(format t "Got signal on root with arg ~S~%" s)
(force-output))
(defun publish-example ()
(handler-case
(with-open-bus (bus (session-server-addresses))
(format t "Bus connection name: ~A~%" (bus-name bus))
(dbus:add-match bus :type :signal :interface "org.adeht.MyService")
(publish-objects bus))
(end-of-file ()
:disconnected-by-bus)))
;; was missing the 'add-match
;; and now let's try to catch the NotificationClosed tihngy
;; enefedov@LLF33A87M:~$ dbus-send --session --type=signal /org/adeht/MyService org.adeht.MyService.OnSignal string:"Hello yayyaline"
;; and when i do signal-handler on 'root
;; $ dbus-send --session --type=signal /org/adeht/MyService org.adeht.MyService.OnSignal ;; this is how to send it
;; so! i need to create it on the object path, ok

377
playground.lisp Normal file
View File

@ -0,0 +1,377 @@
;; for the sly to use dynamibly decided sbcl impl, to pick up wrappers
;; with packages?
;; (setq inferior-lisp-program "/bin/env sbcl")
;; so. what? load dbus library and try out examples?
;; maybe i want to try some of the simpler function calls
;; and then get to screen sharing dialog, and print some info on frames?
;; https://nixos.org/manual/nixpkgs/stable/#lisp-building-wrappers
(load (sb-ext:posix-getenv "ASDF"))
(asdf:load-system 'alexandria)
(asdf:load-system 'dbus)
;; https://blog.macrolet.net/posts/DBus-and-PolicyKit-from-Common-Lisp.html
(defpackage #:example
(:use #:cl #:dbus))
(in-package #:example)
(with-open-bus (bus (system-server-addresses))
(with-introspected-object (authority bus
"/org/freedesktop/PolicyKit1/Authority"
"org.freedesktop.PolicyKit1")
(let* ((subject `("system-bus-name" (("name" ((:string) ,(bus-name bus))))))
(action-id "org.freedesktop.policykit.exec")
(details ())
(flags 1)
(cancellation-id "")
(result
(authority "org.freedesktop.PolicyKit1.Authority" "CheckAuthorization"
subject action-id details flags cancellation-id)))
(format T "~A~%" result))))
(dbus/server-addresses:system-server-addresses)
(system-server-addresses)
;; C-c is sly-prefix-map
(with-open-bus (bus (session-server-addresses))
(with-introspected-object (notification bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
(notification "org.freedesktop.Notifications" "Notify"
"Test" 0 "" "Test" "This is a test; I repeat, this is a test." '() '() -1)
))
;; ok, but how do i introspect which parameters i need to pass to the call?
;; i could use
;;$ qdbus org.freedesktop.Notifications /org/freedesktop/Notifications
;; from kdePackages.qttools
;; but i'd prefer from cl
(with-open-bus (bus (session-server-addresses))
(list-names bus))
(with-open-connection (bus (make-instance 'iomux:event-base) (session-server-addresses))
(let ((obj (make-object-from-introspection bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")))
(format T "hello")
(format T "~A" obj)))
;; sly-macroexpand-1
;; (let ((bus
;; (open-connection (make-instance 'iolib/multiplex:event-base)
;; (session-server-addresses) :if-failed :error)))
;; (unwind-protect
;; (progn
;; (make-object-from-introspection bus "/org/freedesktop/Notifications"
;; "org.freedesktop.Notifications"))
;; (when bus (close-connection bus))))
;; oh, ok. make-object-from-introspection can be subsctituted with convenience
;; ' with-introspected-object' and that's already in examples
;; so convenience does hide the multiplexers and connecitons
(with-open-bus (bus (session-server-addresses))
(list-names bus ))
;; "org.freedesktop.Notifications"
(with-open-bus (bus (session-server-addresses))
(get-managed-objects bus "org.freedesktop.Notifications" ))
;; wait, what if i just use 'object in the forms passed to 'with-introspected-object'?
;; and gensyms pick it up? :shrug:
(with-open-bus (bus (session-server-addresses))
(get-managed-objects bus "org.freedesktop.Notifications" "/org/freedesktop/Notifications" ))
;; nope
;; ok, found another example maybe
;; https://github.com/lucashpandolfo/udisks
;; well, maybe it should work?
(with-open-bus (bus (session-server-addresses))
(get-managed-objects bus "org.gtk.vfs.AfcVolumeMonitor" "/org/gtk/Private/RemoteVolumeMonitor" ))
;; ok, maybe these servcies don't have managed objects?
;; otherwise they would have ObjectManager interface or something
;; so let's try to figure out which interface I need to add for
;; get-all-properties to work
(with-open-bus (bus (session-server-addresses))
(get-all-properties bus "org.freedesktop.Notifications"
"/org/freedesktop/Notifications"
"org.freedesktop.Notifications"))
;; nil, but maybe because it has methods, not properties?
(with-open-bus (bus (session-server-addresses))
(get-all-properties bus "org.freedesktop.portal.Desktop" "/org/freedesktop/portal/desktop" "org.freedesktop.portal.ScreenCast"))
;; (("AvailableSourceTypes" 0) ("AvailableCursorModes" 0) ("version" 4))
;; ok, so this is getting properties. cool
;; next - figuring out how to check method signatures?
;; should be possible no?
;; oh, maybe i should use 'make-object-from-introspection directly
;; but where do i get "connection?"
(format T "well")
(iolib/multiplex:with-event-base (event-base)
(format T "yoyo")
(with-open-connection (connection event-base (session-server-addresses))
(format T "in connection ~A" connection)
(let ((introspection (dbus/introspect:fetch-introspection-document connection "/org/freedesktop/Notifications" "org.freedesktop.Notifications")))
(format T "Introspection: ~A" introspection))
(let ((obj (make-object-from-introspection connection "/org/freedesktop/Notifications" "org.freedesktop.Notifications")))
(format T "hello")
(format T "~A" obj))))
(with-open-bus (my-bus (session-server-addresses))
(handler-case
(let ((props (dbus:get-all-properties my-bus "org.freedesktop.Notifications" "/org/freedesktop/Notifications" "org.freedesktop.Notifications")))
(format T "Notification properties: ~A~%" props))
(error (e)
(format T "Error getting properties: ~pA~%" e))))
;; well, strange
;; https://old.reddit.com/r/lisp/comments/179zl1/has_anyone_else_used_the_dbus_package_much/
(progn
(setf upower_conn
(open-connection
(make-instance 'iolib.multiplex:event-base) (system-server-addresses)))
(authenticate (supported-authentication-mechanisms upower_conn) upower_conn)
(hello upower_conn)
(invoke-method upower_conn "Introspect"
:path "/org/freedesktop/UPower"
:destination "org.freedesktop.UPower"
:interface "org.freedesktop.DBus.Introspectable"))
(progn
(setf upower_conn
(open-connection
(make-instance 'iolib.multiplex:event-base) (system-server-addresses)))
(authenticate (supported-authentication-mechanisms upower_conn) upower_conn)
(hello upower_conn)
(setf bat0_obj
(make-object-from-introspection
upower_conn
"/org/freedesktop/UPower/devices/battery_BAT0"
"org.freedesktop.UPower"))
(object-invoke bat0_obj "org.freedesktop.DBus.Properties" "GetAll" "org.freedesktop.UPower.Device"))
;; ok, so this works.
;; from 11 years ago, cool
;; creating object from introspection
;; doing invoke, but similar to with-object
;; let's try get object for Notification
;; and then try to print object and stuff
(iolib/multiplex:with-event-base (event-base)
(with-open-connection (connection event-base (session-server-addresses))
(authenticate (supported-authentication-mechanisms connection) connection)
(hello connection)
(let ((obj (make-object-from-introspection connection "/org/freedesktop/Notifications" "org.freedesktop.Notifications")))
(print-object obj nil)
(list-object-interfaces obj))))
;; ok, so this works?
;; i needed both authenticate and hello, cool
;; thank you https://old.reddit.com/r/lisp/comments/179zl1/has_anyone_else_used_the_dbus_package_much/
;; (#<DBUS/INTROSPECT::INTERFACE "org.freedesktop.Notifications">
;; #<DBUS/INTROSPECT::INTERFACE "org.dunstproject.cmd0">
;; #<DBUS/INTROSPECT::INTERFACE "org.freedesktop.DBus.Peer">
;; #<DBUS/INTROSPECT::INTERFACE "org.freedesktop.DBus.Introspectable">
;; #<DBUS/INTROSPECT::INTERFACE "org.freedesktop.DBus.Properties">)
;; wowy, yeay!
;; i guess maybe now let's try to list interface on Desktop, which will have ScreenCast
(iolib/multiplex:with-event-base (event-base)
(with-open-connection (connection event-base (session-server-addresses))
(authenticate (supported-authentication-mechanisms connection) connection)
(hello connection)
(let ((obj (make-object-from-introspection connection "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")))
(print-object obj nil)
(list-object-interfaces obj))))
;; nice!
;; so, what to try next though?
;; i wanted a way to check the funciton signatures
;; maybe for this one?
;; #<DBUS/INTROSPECT::INTERFACE "org.freedesktop.portal.Screenshot">
;; how do i get methods of an interface?
;; oh, so 'list-object-interfaces only returns values from hashmap that obj
;; already contains
(iolib/multiplex:with-event-base (event-base)
(with-open-connection (connection event-base (session-server-addresses))
(authenticate (supported-authentication-mechanisms connection) connection)
(hello connection)
(let ((obj (make-object-from-introspection connection "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")))
(list-interface-methods (object-interface "org.freedesktop.portal.Screenshot" obj)))))
;; (#<DBUS/INTROSPECT::METHOD "PickColor" sa{sv}>
;; #<DBUS/INTROSPECT::METHOD "Screenshot" sa{sv}>)
;; ok, here are sa{sv} types of parameters, maybe this is it
;; i suppose next is figuring out how to call
;; let's read more general stuff about dbus then?
;; https://develop.kde.org/docs/features/d-bus/accessing_dbus_interfaces/
;; i think this is in C with qt library, but ok
;; here's about Variants https://doc.qt.io/qt-5/qvariant.html
;; what's that?
;; ok, now examples should be more understandable
;; https://github.com/death/dbus/blob/8bba6a0942232e9d7fa915b33bbe32dfedc5abb9/examples/notify.lisp
;; https://github.com/death/dbus/blob/8bba6a0942232e9d7fa915b33bbe32dfedc5abb9/examples/publish.lisp
;; maybe. let's try to call something with screenshots, let's go
;; https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Screenshot.html
(iolib/multiplex:with-event-base (event-base)
(with-open-connection (connection event-base (session-server-addresses))
(authenticate (supported-authentication-mechanisms connection) connection)
(hello connection)
(let ((obj (make-object-from-introspection connection "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")))
(list-interface-methods (object-interface "org.freedesktop.portal.Screenshot" obj)))))
;; for the sa{sv} looking into documentation
;; https://dbus.freedesktop.org/doc/dbus-specification.html#type-system
;; so for screenshot it's string, then array of dict entry string->variant
(with-open-bus (bus (session-server-addresses))
(with-introspected-object (desktop bus "/org/freedesktop/portal/desktop" "org.freedesktop.portal.Desktop")
(desktop "org.freedesktop.portal.Screenshot" "Screenshot" "" '())))
;; dbus-send --session --dest=org.freedesktop.portal.Screenshot --type=method_call --print-reply /org/freedesktop/portal/desktop org.freedesktop.portal.Screenshot
;; well, calling Screenshot from the qdbusviewer doesn't work
;; maybe it can work from code,
;; not quite found an easy answer, but here's code for flameshot
;; https://github.com/flameshot-org/flameshot/blob/c1dac52231024174faa68a29577129ebca125dff/src/utils/screengrabber.cpp#L59
(iolib/multiplex:with-event-base (event-base)
(with-open-connection (connection event-base (session-server-addresses))
(authenticate (supported-authentication-mechanisms connection) connection)
(hello connection)
(let ((obj (make-object-from-introspection connection "/org/adeht/MyService" "org.adeht.MyService")))
(list-interface-methods (object-interface "org.adeht.MyService" obj))
))) ; missing Introspecable on the service defined through death/dbus
;; that's because 8 months ago introspection publishing was changed to be done by default
;; and my version is older, i could try to set up separate action from removed example?
;; but better to try to update
(with-open-bus (bus (session-server-addresses))
(with-introspected-object (desktop bus "/org/adeht/MyService" "org.adeht.MyService")
(desktop "org.adeht.MyService" "my-method" "hello")))
;; trying from another discussion
;; still trying to receive a signal
(define-dbus-object root
(:path "/"))
(dbus:define-dbus-object my-notifications-service
(:path "/org/freedesktop/Notifications")
(:parent root))
;; (dbus:define-dbus-signal-handler (my-notifications-service notification-closed) ()
;; (:interface "org.freedesktop.Notifications")
;; (format t "Got notification closed without parameters" )
;; (force-output))
(dbus:define-dbus-signal-handler (my-notifications-service notification-closed) ((id :uint32) (reason :uint32))
(:interface "org.freedesktop.Notifications")
(format t "Got notification closed with parameters ~A ~A" id reason)
(force-output))
(define-dbus-signal-handler (my-notifications-service on-non-notification-end-signal) ((s :string))
(:interface "org.adeht.MyService")
(format t "Got signal with arg ~S~%" s)
(force-output))
(defun example-listen-to-notification ()
(handler-case
(dbus:with-open-bus (bus (session-server-addresses))
; (dbus:add-match bus :type :signal :interface "org.freedesktop.Notifications" :member "NotificationClosed")
; (dbus:add-match bus :type :signal :interface "org.adeht.MyService")
(dbus:add-match bus :type :signal :path "/org/freedesktop/Notifications")
(format t "Bus connection name: ~A~%" (dbus:bus-name bus))
(dbus:publish-objects bus))
(end-of-file ()
:disconnected-by-bus)))
;; signal time=1719758221.505386 sender=:1.64 -> destination=:1.162 serial=83 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=NotificationClosed
;; uint32 15
;; uint32 2
(with-open-bus (bus (session-server-addresses))
(with-introspected-object (notification bus "/org/freedesktop/Notifications" "org.freedesktop.Notifications")
(notification "org.freedesktop.Notifications" "Notify"
"Test" 0 "" "Test" "This is a test; I repeat, this is a test." '() '() -1)
))
;; yes, i re-declared signal handler without parameters and now it catches
;; the
;; goood!
;; but it doesn't catch when i actually close the notification
;; maybe because of parameters?
;; oh, maybe uint32 are not the ones i had before in the signature
;; this works for my extra interface handler:
;; $ dbus-send --session --type=signal /org/freedesktop/Notifications org.adeht.MyService.OnNonNotificationEndSignal string:"Hello yayyaline"
;; huh. so manual with uint32 works
;; dbus-send --session --type=signal /org/freedesktop/Notifications org.freedesktop.Notifications.NotificationClosed uint32:4 uint32:8
;; and if i only define without params, then manual without params works
;; dbus-send --session --type=signal /org/freedesktop/Notifications org.freedesktop.Notifications.NotificationClosed
;; but the one from actually closed notification doesn't work?
;; in dbus-monitor one from actually closing:
;; signal time=1719765073.249989 sender=:1.45 -> destination=:1.112 serial=51 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=NotificationClosed
;; uint32 11
;; uint32 2
;; and from manual invocation:
;; signal time=1719765156.257421 sender=:1.115 -> destination=(null destination) serial=2 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=NotificationClosed
;; uint32 2222
;; uint32 11111
;; is there any visible difference?
;; aaand, yeah, i get with manual and dont get with actual
;; aaand, yes.
;; when signal has "destination" set - it's not broadcasted,
;; so, not everyone gets it. when i do actual closing of notification
;; the resulting NotificationClosed is likely sent to caller
;; and my code doesn't receive it, coool
;; $ dbus-send --session --type=signal --dest=:1.108 /org/freedesktop/Notifications org.freedesktop.Notifications.NotificationClosed uint32:777 uint32:333
;; this works - when i match with a name from "Bus connection name"
;; yay. i suppose
;; now what would be an example of broadcasted signal that i could listen to
;; in my example
;; let's do safeeyes icon change:
;; signal time=1719766048.367111 sender=:1.34 -> destination=(null destination) serial=101 path=/org/ayatana/NotificationItem/safeeyes_2; interface=org.kde.StatusNotifierItem; member=NewIcon
(dbus:define-dbus-object my-safeeyes-listener
(:path "/org/ayatana/NotificationItem/safeeyes_2"))
(dbus:define-dbus-signal-handler (my-safeeyes-listener new-icon) ()
(:interface "org.kde.StatusNotifierItem")
(format t "Got notification on the safeeyes icon change~%" )
(force-output))
(defun example-listen-to-safeeys ()
(handler-case
(dbus:with-open-bus (bus (session-server-addresses))
(dbus:add-match bus :type :signal :interface "org.kde.StatusNotifierItem")
(format t "Bus connection name: ~A~%" (dbus:bus-name bus))
(dbus:publish-objects bus))
(end-of-file ()
:disconnected-by-bus)))