WEBVTT captioned by sachac NOTE What is D-Bus? 00:00:00.000 --> 00:00:04.879 Welcome to my EmacsConf 2022 talk, The Wheels on D-Bus. 00:00:04.880 --> 00:00:07.439 In this talk, we'll cover what D-Bus is, 00:00:07.440 --> 00:00:10.759 why you might want to use it, and how to use it with Emacs. 00:00:10.760 --> 00:00:13.679 D-Bus is fundamentally based on passing messages 00:00:13.680 --> 00:00:16.999 in between processes, using the bus as a mediator. 00:00:17.000 --> 00:00:20.599 On top of this is built an RPC system with method invocation 00:00:20.600 --> 00:00:22.799 that has argument lists and return values, 00:00:22.800 --> 00:00:25.479 like you might find in any programming language. 00:00:25.480 --> 00:00:27.839 These are commonly used for verb-type actions 00:00:27.840 --> 00:00:29.999 like "restart my computer." 00:00:30.000 --> 00:00:32.639 You can also associate a collection of attributes 00:00:32.640 --> 00:00:35.839 with objects on the bus, and these are called properties. 00:00:35.840 --> 00:00:39.839 The properties can be read-only, write-only, or read-write. 00:00:39.840 --> 00:00:43.159 Signals are a way of notifying participants on the bus 00:00:43.160 --> 00:00:45.999 of updated state, and are the basis 00:00:46.000 --> 00:00:47.799 for building dynamic user interfaces 00:00:47.800 --> 00:00:50.479 that react to changes in the system. 00:00:50.480 --> 00:00:52.759 It has a static and strong type system, 00:00:52.760 --> 00:00:55.359 so if you send a message with the wrong type signature, 00:00:55.360 --> 00:00:57.839 it simply gets rejected instead of going through 00:00:57.840 --> 00:00:59.599 to the remote service. 00:00:59.600 --> 00:01:02.319 It also manages service life cycles, 00:01:02.320 --> 00:01:04.399 so you're not running services at all times. 00:01:04.400 --> 00:01:07.879 They can be started and stopped by D-Bus on demand. NOTE Why D-Bus? 00:01:07.880 --> 00:01:10.519 D-Bus has two major use cases. 00:01:10.520 --> 00:01:13.359 The first is acting as a lower-level substrate 00:01:13.360 --> 00:01:14.679 for higher-level programs, 00:01:14.680 --> 00:01:16.919 like a graphical desktop environment. 00:01:16.920 --> 00:01:19.599 For example, if you want to manage your network connectivity 00:01:19.600 --> 00:01:21.239 from your graphical environment, 00:01:21.240 --> 00:01:23.919 instead of having to build all of that from the ground up, 00:01:23.920 --> 00:01:26.239 you can rely on the D-Bus service to do that 00:01:26.240 --> 00:01:28.679 and only build the graphical component of it. 00:01:28.680 --> 00:01:31.319 This gives you consistency between desktop environments 00:01:31.320 --> 00:01:33.799 and reduces code duplication. 00:01:33.800 --> 00:01:37.319 Another application is automating desktop programs. 00:01:37.320 --> 00:01:39.279 If your program offers a D-Bus service, 00:01:39.280 --> 00:01:40.959 then it can be remote-controlled, 00:01:40.960 --> 00:01:42.759 and if all of your programs offer D-Bus, 00:01:42.760 --> 00:01:45.359 you can control your entire desktop. NOTE The D-Bus Model 00:01:45.360 --> 00:01:48.559 Let's look at the abstractions that D-Bus provides. 00:01:48.560 --> 00:01:51.239 The top level object is called a bus, 00:01:51.240 --> 00:01:52.359 and it's like a partition 00:01:52.360 --> 00:01:54.919 that messages get exchanged inside of. 00:01:54.920 --> 00:01:57.279 Messages don't cross buses. 00:01:57.280 --> 00:01:59.559 Inside of a bus are services. 00:01:59.560 --> 00:02:03.159 Services are normally identified in reverse FQDN order, 00:02:03.160 --> 00:02:06.159 so org.foobar.FooService. 00:02:06.160 --> 00:02:08.599 Each service provides some set of features 00:02:08.600 --> 00:02:11.759 related to a particular area of functionality. 00:02:11.760 --> 00:02:14.439 Inside of each service are objects. 00:02:14.440 --> 00:02:16.599 Objects use a path notation, 00:02:16.600 --> 00:02:19.759 and usually follow the same reverse FQDN format 00:02:19.760 --> 00:02:21.959 as the service identifier. 00:02:21.960 --> 00:02:24.879 Each object has one or more interfaces. 00:02:24.880 --> 00:02:27.279 An interface is like a facet that you can use 00:02:27.280 --> 00:02:29.479 to interact with an object, 00:02:29.480 --> 00:02:32.239 and inside of the interface are properties, methods, 00:02:32.240 --> 00:02:33.999 and signals, which we covered before. 00:02:34.000 --> 00:02:37.039 Properties are attributes that can be read or written. 00:02:37.040 --> 00:02:40.239 Methods are verbs that you can call to invoke an action, 00:02:40.240 --> 00:02:43.319 and a signal is something that's used to move state 00:02:43.320 --> 00:02:47.239 in between a service and another participant on the bus. 00:02:47.240 --> 00:02:49.599 There can be any number of interfaces on an object, 00:02:49.600 --> 00:02:51.479 any number of objects in a service, 00:02:51.480 --> 00:02:53.439 and any number of services on a bus, 00:02:53.440 --> 00:02:55.359 and any number of buses on a system. NOTE Well-known Busses 00:02:55.360 --> 00:03:00.039 There are two well-known busses, 00:03:00.040 --> 00:03:02.359 and these roughly map to those two use cases 00:03:02.360 --> 00:03:03.639 I mentioned before. 00:03:03.640 --> 00:03:06.479 The system bus is for interfacing with hardware 00:03:06.480 --> 00:03:08.439 and operating-system-level concerns 00:03:08.440 --> 00:03:11.679 like disks, networks, and so forth. 00:03:11.680 --> 00:03:14.319 The session bus is tied to a user login, 00:03:14.320 --> 00:03:19.999 and is more in the desktop automation use case. NOTE Common interfaces 00:03:20.000 --> 00:03:21.919 There are some common interfaces you'll find 00:03:21.920 --> 00:03:23.959 if you go exploring D-Bus. 00:03:23.960 --> 00:03:25.999 The Introspectable interface is the basis 00:03:26.000 --> 00:03:27.919 of a lot of the reflection features. 00:03:27.920 --> 00:03:30.119 It has a single method called introspect 00:03:30.120 --> 00:03:32.239 that returns the XML interface description 00:03:32.240 --> 00:03:33.399 of whatever you call it on. 00:03:33.400 --> 00:03:36.559 Peer is used for lower level connectivity, 00:03:36.560 --> 00:03:39.679 for example, pinging a service to see if it's running. 00:03:39.680 --> 00:03:41.759 And the Properties interface is the basis 00:03:41.760 --> 00:03:43.119 of the read-write properties, 00:03:43.120 --> 00:03:45.799 which are secretly method calls under the cover. 00:03:45.800 --> 00:03:48.519 Just about every object you interact with on D-Bus 00:03:48.520 --> 00:03:51.399 will support all three of these interfaces. 00:03:51.400 --> 00:03:54.759 Additionally, ObjectManager is used for services 00:03:54.760 --> 00:03:56.759 that manage collections of objects. 00:03:56.760 --> 00:03:59.839 For example, the disk service has an object 00:03:59.840 --> 00:04:01.279 for each disk that's attached, 00:04:01.280 --> 00:04:02.799 and the object manager allows you 00:04:02.800 --> 00:04:06.239 to enumerate all of those. NOTE Emacs Native D-Bus 00:04:06.240 --> 00:04:10.359 Emacs supports D-Bus natively since version 23.1. 00:04:10.360 --> 00:04:12.119 It's a combination of native bindings 00:04:12.120 --> 00:04:14.639 with a C library and dbus.el. 00:04:14.640 --> 00:04:17.559 While there are some ports of D-Bus 00:04:17.560 --> 00:04:19.479 to non-Linux operating systems, 00:04:19.480 --> 00:04:22.039 it's probably only available on Linux 00:04:22.040 --> 00:04:24.439 and almost certainly only usable on Linux. 00:04:24.440 --> 00:04:28.919 If you want to interact with D-Bus from Emacs, 00:04:28.920 --> 00:04:30.079 it's fairly straightforward. 00:04:30.080 --> 00:04:33.199 There's a collection of functions like `dbus-get-property' 00:04:33.200 --> 00:04:35.039 or `dbus-call-method', et cetera, 00:04:35.040 --> 00:04:37.639 and they almost all take this same set 00:04:37.640 --> 00:04:39.319 of four arguments at the beginning: 00:04:39.320 --> 00:04:42.119 bus, service, path, and interface. 00:04:42.120 --> 00:04:45.439 In this case, it takes a single additional property, 00:04:45.440 --> 00:04:46.599 which is the one to read. 00:04:46.600 --> 00:04:49.679 And what we're calling is the hostname1 service, 00:04:49.680 --> 00:04:51.519 which gives you just a little bit of information 00:04:51.520 --> 00:04:54.759 about the system, like its hostname or its chassis. 00:04:54.760 --> 00:04:56.199 And in this case, you can see I'm running 00:04:56.200 --> 00:04:57.719 this presentation off my laptop. 00:04:57.720 --> 00:05:00.959 The problem with this and what I don't like about it 00:05:00.960 --> 00:05:04.599 is that all of these identifiers are very verbose 00:05:04.600 --> 00:05:05.719 and very repetitive. 00:05:05.720 --> 00:05:07.679 And if you end up calling these a lot, 00:05:07.680 --> 00:05:09.319 it gets old really quickly. NOTE Debase 00:05:09.320 --> 00:05:12.999 So I wrote a wrapper called Debase, 00:05:13.000 --> 00:05:15.839 which is convenience on top of the built-in functions. 00:05:15.840 --> 00:05:18.839 Most of the stock functions have Debase versions 00:05:18.840 --> 00:05:21.519 just by replacing "dbus" with "debase". 00:05:21.520 --> 00:05:23.879 And let's look how that works. NOTE Debase: Objects 00:05:23.880 --> 00:05:27.999 The fundamental idea of Debase is that you can bind together 00:05:28.000 --> 00:05:30.319 all of those arguments into a single object 00:05:30.320 --> 00:05:31.559 that represents the endpoint. 00:05:31.560 --> 00:05:35.599 This is an EIEIO class, and it takes keyword arguments, 00:05:35.600 --> 00:05:36.879 so there's never any chance 00:05:36.880 --> 00:05:38.559 of mixing up which thing is what. 00:05:38.560 --> 00:05:41.479 So this sets the endpoint to that object, 00:05:41.480 --> 00:05:43.119 calls `debase-get-property' on it, 00:05:43.120 --> 00:05:45.039 and you can see it works exactly the same. 00:05:45.040 --> 00:05:47.359 The thing that's really nice about this, though, 00:05:47.360 --> 00:05:50.199 is it knows that so many of these arguments 00:05:50.200 --> 00:05:52.919 are very similar that it can compute most of them 00:05:52.920 --> 00:05:54.279 if you don't provide them all. 00:05:54.280 --> 00:05:57.159 So if you just say service, it will assume 00:05:57.160 --> 00:05:59.159 that you want the same object that matches 00:05:59.160 --> 00:06:00.879 and the same interface that matches, 00:06:00.880 --> 00:06:02.319 and it works just the same. 00:06:02.320 --> 00:06:04.879 I find this very, very convenient. 00:06:04.880 --> 00:06:07.239 You can also reuse the object 00:06:07.240 --> 00:06:09.159 instead of having to repeat every argument 00:06:09.160 --> 00:06:10.399 with every function call, 00:06:10.400 --> 00:06:13.439 which is a really great improvement in ergonomics. NOTE Debase: Retarget objects 00:06:13.440 --> 00:06:18.119 Because so many objects have multiple interfaces, 00:06:18.120 --> 00:06:20.319 you often find yourself needing to look 00:06:20.320 --> 00:06:22.479 at a different aspect of that object. 00:06:22.480 --> 00:06:26.599 This is supported with the built-in EIEIO `clone' method, 00:06:26.600 --> 00:06:28.279 which takes an object 00:06:28.280 --> 00:06:30.439 and a set of keyword arguments to replace. 00:06:30.440 --> 00:06:32.599 So in this case, we can see we're calling 00:06:32.600 --> 00:06:33.479 the Properties method, 00:06:33.480 --> 00:06:35.799 but everything else on that endpoint is the same. 00:06:35.800 --> 00:06:38.079 And then we're gonna call the method GetAll 00:06:38.080 --> 00:06:39.359 on that Properties interface, 00:06:39.360 --> 00:06:41.119 and it's going to return all the properties 00:06:41.120 --> 00:06:43.919 of the org.freedesktop.hostname1 interface 00:06:43.920 --> 00:06:45.199 inside of that object. 00:06:45.200 --> 00:06:48.199 And if we run that, we can see there's the hostname 00:06:48.200 --> 00:06:50.159 and some other information about the laptop 00:06:50.160 --> 00:06:51.079 that I'm running this on. NOTE Debase: Object binding 00:06:51.080 --> 00:06:54.399 Debase also supports object binding. 00:06:54.400 --> 00:06:58.559 This creates a lexical context in which the Debase object 00:06:58.560 --> 00:07:01.119 is the implicit target of any D-Bus function. 00:07:01.120 --> 00:07:03.279 This is really convenient if you need 00:07:03.280 --> 00:07:06.479 to fetch multiple properties or otherwise interact 00:07:06.480 --> 00:07:09.319 with the same endpoint in multiple different ways. 00:07:09.320 --> 00:07:11.359 And you can see I'm still on a laptop 00:07:11.360 --> 00:07:12.479 and it's still named meson. NOTE Debase: Raw binding 00:07:12.480 --> 00:07:16.319 You can also, if you don't want to use the object, 00:07:16.320 --> 00:07:18.239 you can provide the raw argument list. 00:07:18.240 --> 00:07:20.919 Under the covers, this is basically an `flet' 00:07:20.920 --> 00:07:23.279 where you're currying all of these functions 00:07:23.280 --> 00:07:25.439 so they start with those argument lists. 00:07:25.440 --> 00:07:27.799 And you can see I'm running on a Linux machine, 00:07:27.800 --> 00:07:29.399 which should not be surprising. NOTE Debase: Codegen 00:07:29.400 --> 00:07:34.079 Debase also has an experimental code generation feature. 00:07:34.080 --> 00:07:38.359 It outputs EIEIO code with one class per D-Bus interface. 00:07:38.360 --> 00:07:41.079 This includes accessors for all of its properties 00:07:41.080 --> 00:07:44.159 with an in-process cache, so if you read one property, 00:07:44.160 --> 00:07:46.399 you don't have to go back to the bus to read it again. 00:07:46.400 --> 00:07:50.119 It also outputs generic functions and method implementations 00:07:50.120 --> 00:07:52.199 for the D-Bus interface methods. 00:07:52.200 --> 00:07:54.279 It includes name-mangling options, 00:07:54.280 --> 00:07:56.879 so you can control how everything is named. 00:07:56.880 --> 00:07:58.639 And you can generate the code either 00:07:58.640 --> 00:08:00.279 via introspecting a live system 00:08:00.280 --> 00:08:02.639 or providing an XML interface description, 00:08:02.640 --> 00:08:04.279 which is handy if you want to use it 00:08:04.280 --> 00:08:05.919 as part of a non-interactive build. 00:08:05.920 --> 00:08:08.159 I think this has a lot of promise, 00:08:08.160 --> 00:08:09.679 but it doesn't feel quite right yet, 00:08:09.680 --> 00:08:14.199 so any feedback or contributions are very welcome. NOTE Debase: Codegen example 00:08:14.200 --> 00:08:16.919 Let's generate some Elisp code 00:08:16.920 --> 00:08:19.639 for that hostname1 service we were interacting with before. 00:08:19.640 --> 00:08:23.119 `debase-gen-class' is the generation class, 00:08:23.120 --> 00:08:26.079 and it says to create a class that matches this interface, 00:08:26.080 --> 00:08:28.999 named "hostname1", and then the rest of these arguments 00:08:29.000 --> 00:08:30.999 are the same ones to target the endpoint, 00:08:31.000 --> 00:08:32.919 just like with `debase-object', 00:08:32.920 --> 00:08:34.759 because it extends `debase-object'. 00:08:34.760 --> 00:08:37.679 `debase-gen-code' is a generic function 00:08:37.680 --> 00:08:40.119 that takes any `debase-gen' class. 00:08:40.120 --> 00:08:42.279 There are different classes for functions, 00:08:42.280 --> 00:08:43.359 properties, et cetera, 00:08:43.360 --> 00:08:45.479 and it creates all of the code for it. 00:08:45.480 --> 00:08:48.279 If we evaluate it, we can see the results 00:08:48.280 --> 00:08:49.959 look about like we would expect: 00:08:49.960 --> 00:08:52.159 creates a defclass named "hostname1", 00:08:52.160 --> 00:08:53.879 which extends `debase-object', 00:08:53.880 --> 00:08:56.639 has all of the slots and accessors defined, 00:08:56.640 --> 00:08:59.319 and then methods that define everything 00:08:59.320 --> 00:09:01.839 that you might want to do with it, including documentation. 00:09:01.840 --> 00:09:04.759 This is based on introspecting a running system, 00:09:04.760 --> 00:09:05.479 but as I mentioned, 00:09:05.480 --> 00:09:08.039 you can provide an XML interface description instead, 00:09:08.040 --> 00:09:08.679 if you like. NOTE Debase: ObjectManager 00:09:08.680 --> 00:09:12.279 Debase also comes with `debase-objectmanager', 00:09:12.280 --> 00:09:15.399 which is convenience for the D-Bus ObjectManager interface. 00:09:15.400 --> 00:09:17.999 This is used in a lot of places in D-Bus, 00:09:18.000 --> 00:09:20.279 where an object manages other objects. 00:09:20.280 --> 00:09:22.719 For example, the NetworkManager object 00:09:22.720 --> 00:09:25.159 manages network hardware objects, 00:09:25.160 --> 00:09:26.879 and using the ObjectManager interface, 00:09:26.880 --> 00:09:28.879 you can enumerate all of the network hardware, 00:09:28.880 --> 00:09:31.039 and by subscribing to the signals, 00:09:31.040 --> 00:09:32.999 you can be notified when they change. 00:09:33.000 --> 00:09:35.999 `debase-objectmanager' keeps a local cache, 00:09:36.000 --> 00:09:38.119 and will fire a callback on any change. 00:09:38.120 --> 00:09:41.239 So it's the building block for that dynamic user interface, 00:09:41.240 --> 00:09:43.119 like you would see in a desktop system, 00:09:43.120 --> 00:09:44.479 but inside of Emacs. NOTE Demo: Discomfort 00:09:44.480 --> 00:09:47.759 Let's do some demos. 00:09:47.760 --> 00:09:51.039 Discomfort is an interface I wrote for UDisks2, 00:09:51.040 --> 00:09:53.719 which is what manages all of the block device hardware. 00:09:53.720 --> 00:09:57.679 And again, it has that dynamic desktop-like interactivity, 00:09:57.680 --> 00:10:00.279 and mostly will just do what you mean. 00:10:00.280 --> 00:10:03.519 This is definitely alpha state. 00:10:03.520 --> 00:10:04.839 It doesn't have all the features, 00:10:04.840 --> 00:10:06.559 but it's good enough that I use it daily. 00:10:06.560 --> 00:10:08.879 So here's Discomfort, 00:10:08.880 --> 00:10:11.679 and you can see it has a list of all your hardware, 00:10:11.680 --> 00:10:13.639 what type it is, and where it's mounted. 00:10:13.640 --> 00:10:16.199 I have a little USB extension cable here, 00:10:16.200 --> 00:10:17.679 and I'm gonna plug in a disc, 00:10:17.680 --> 00:10:19.319 just to show you how this works. 00:10:19.320 --> 00:10:21.079 You can see when I plug it in, 00:10:21.080 --> 00:10:22.399 just a moment later, 00:10:22.400 --> 00:10:24.439 it shows up in that list, automatically. 00:10:24.440 --> 00:10:25.719 I don't have to press any key, 00:10:25.720 --> 00:10:27.759 I don't have to refresh it, it's just there. 00:10:27.760 --> 00:10:29.519 If I unplug it, it's gone. 00:10:29.520 --> 00:10:30.719 Plug it back in, 00:10:30.720 --> 00:10:33.399 and there it is. 00:10:33.400 --> 00:10:35.239 And you can see it's an encrypted volume. 00:10:35.240 --> 00:10:37.279 So in order to do anything with this, 00:10:37.280 --> 00:10:38.679 I'm going to have to supply a password. 00:10:38.680 --> 00:10:41.759 Just pressing Enter goes into the "do what I mean" mode, 00:10:41.760 --> 00:10:43.519 and it asks for the password. 00:10:43.520 --> 00:10:46.599 In this case, I've chosen the very secure password 00:10:46.600 --> 00:10:47.559 of "password". 00:10:47.560 --> 00:10:51.199 I hit Enter, and it unlocks it, and it mounts it, 00:10:51.200 --> 00:10:53.319 and it opens `dired' looking at it. 00:10:53.320 --> 00:10:54.439 And here's a little README. 00:10:54.440 --> 00:10:55.559 Let's see what it says. 00:10:55.560 --> 00:10:58.559 "Hello, EmacsConf." 00:10:58.560 --> 00:11:01.479 So that's my demo of discomfort. NOTE Demo: Remote eval 00:11:01.480 --> 00:11:05.839 In addition to acting as a client for D-Bus, 00:11:05.840 --> 00:11:09.359 Emacs can also offer services to other D-Bus clients. 00:11:09.360 --> 00:11:11.959 This is a really interesting opportunity 00:11:11.960 --> 00:11:14.119 because it allows many different programs 00:11:14.120 --> 00:11:15.279 to integrate with Emacs 00:11:15.280 --> 00:11:17.679 in ways that were previously very difficult. 00:11:17.680 --> 00:11:20.239 You can use this as an alternative to Emacs. 00:11:20.240 --> 00:11:23.199 The difference is D-Bus provides a full API, 00:11:23.200 --> 00:11:24.999 so instead of emacsclient being 00:11:25.000 --> 00:11:26.679 a sort of fire-and-forget system, 00:11:26.680 --> 00:11:30.119 you can actually get results back from the remote operation. 00:11:30.120 --> 00:11:31.999 So here's some code. 00:11:32.000 --> 00:11:35.679 Here's a `dbus-eval' function, which takes a string, 00:11:35.680 --> 00:11:37.359 reads it, and evaluates it, 00:11:37.360 --> 00:11:39.359 and returns whatever that value is. 00:11:39.360 --> 00:11:41.839 Then we have a `debase-bind' block 00:11:41.840 --> 00:11:44.799 that sets up an object on the session bus. 00:11:44.800 --> 00:11:46.839 Again, that's my user login bus. 00:11:46.840 --> 00:11:49.559 It offers this D-Bus service Emacs. 00:11:49.560 --> 00:11:53.399 This is a constant inside of the dbus.el package. 00:11:53.400 --> 00:11:55.439 And again, the path is a constant in there. 00:11:55.440 --> 00:11:57.159 And we're gonna create this interface, 00:11:57.160 --> 00:12:02.519 org.gnu.Emacs.Eval, and then register a method called Eval 00:12:02.520 --> 00:12:04.759 that calls that `dbus-eval' function. 00:12:04.760 --> 00:12:08.119 Pretty straightforward, only a handful of lines of code. 00:12:08.120 --> 00:12:12.399 To test this out, we're going to use the dbus-send utility. 00:12:12.400 --> 00:12:15.399 This is a command line program that interacts with D-Bus. 00:12:15.400 --> 00:12:18.079 We're going to tell it to wait for and print the reply, 00:12:18.080 --> 00:12:20.999 that the message should be sent to the session bus, 00:12:21.000 --> 00:12:22.599 that we're going to talk 00:12:22.600 --> 00:12:25.639 to the org.gnu.Emacs service on that bus, 00:12:25.640 --> 00:12:30.879 and the /org/gnu/Emacs object inside that service. 00:12:30.880 --> 00:12:33.039 On that object, we're gonna interact 00:12:33.040 --> 00:12:35.999 with the org.gnu.Emacs.Eval interface 00:12:36.000 --> 00:12:37.639 and call its Eval method. 00:12:37.640 --> 00:12:40.639 We're gonna call that method with a single string argument, 00:12:40.640 --> 00:12:42.639 which is indicated by the string prefix, 00:12:42.640 --> 00:12:44.999 and then a form to evaluate. 00:12:45.000 --> 00:12:46.999 I actually have to run this from a shell, 00:12:47.000 --> 00:12:49.399 because if I try using it in Org, it wedges. 00:12:49.400 --> 00:12:51.959 org-babel blocks waiting on completion, 00:12:51.960 --> 00:12:54.519 which blocks the D-Bus service from responding. 00:12:54.520 --> 00:12:57.399 I really wish Emacs was multi-threaded. 00:12:57.400 --> 00:12:59.919 But let's try it out. 00:12:59.920 --> 00:13:02.719 So if we run this, we can see that we get a return, 00:13:02.720 --> 00:13:05.239 and that's an unsigned integer of 32 bits 00:13:05.240 --> 00:13:06.439 with a value of 3. 00:13:06.440 --> 00:13:09.959 So like I was saying, this is really a two-way API 00:13:09.960 --> 00:13:11.719 where you can communicate back and forth 00:13:11.720 --> 00:13:13.399 between Emacs and another program. 00:13:13.400 --> 00:13:14.959 It's not just fire-and-forget. 00:13:14.960 --> 00:13:16.279 I think that's really cool. NOTE Demo: Remote Org capture 00:13:16.280 --> 00:13:18.519 Let's try another demo. 00:13:18.520 --> 00:13:20.599 What about a remote org-capture? 00:13:20.600 --> 00:13:22.999 What if you could trigger an org-capture 00:13:23.000 --> 00:13:24.679 from any program on your desktop? 00:13:24.680 --> 00:13:26.239 I think that would be pretty cool. 00:13:26.240 --> 00:13:30.239 And we can see, there it is. 00:13:30.240 --> 00:13:38.919 All right, I think I've got that one covered. 00:13:38.920 --> 00:13:42.319 So I do want to say that remote eval is probably a bad idea 00:13:42.320 --> 00:13:43.479 from a security perspective, 00:13:43.480 --> 00:13:46.759 but the point of this is some quick and dirty demonstrations 00:13:46.760 --> 00:13:49.799 of what can happen and to get people's imaginations flowing, 00:13:49.800 --> 00:13:51.719 because I think this is something 00:13:51.720 --> 00:13:54.079 that offers a lot of promise for Emacs. 00:13:54.080 --> 00:13:57.799 I think having a full-blown Emacs desktop environment 00:13:57.800 --> 00:13:59.879 where it can do all the things that a GNOME 00:13:59.880 --> 00:14:02.759 or a KDE environment can do is very exciting. 00:14:02.760 --> 00:14:06.439 And if you want to have a traditional GUI with Emacs 00:14:06.440 --> 00:14:08.679 as a more integrated participant of it, 00:14:08.680 --> 00:14:11.879 its service mechanism offers a lot of ability to do that. NOTE Future directions 00:14:11.880 --> 00:14:15.999 In the micro sense, I think there's a lot of improvements 00:14:16.000 --> 00:14:19.279 that can be made to either dbus.el or to dbase. 00:14:19.280 --> 00:14:21.639 The main one is handling of the type system. 00:14:21.640 --> 00:14:25.839 Lisp's dynamic type system doesn't mesh particularly well 00:14:25.840 --> 00:14:28.799 with the static strong type system that D-bus offers, 00:14:28.800 --> 00:14:31.359 and having some convenience to assist that 00:14:31.360 --> 00:14:32.639 would be very helpful. 00:14:32.640 --> 00:14:35.319 There's also some weird interfaces. 00:14:35.320 --> 00:14:38.119 For example, some things return identifiers 00:14:38.120 --> 00:14:40.919 as an array of integer code points instead of a string, 00:14:40.920 --> 00:14:43.719 and there should be a common way of handling that. 00:14:43.720 --> 00:14:46.159 I also think that the service support could be improved. 00:14:46.160 --> 00:14:48.039 Even though I gave the demo service, 00:14:48.040 --> 00:14:50.479 it's not really a great D-bus citizen 00:14:50.480 --> 00:14:53.079 because it doesn't offer that introspection mechanism, 00:14:53.080 --> 00:14:55.919 and so the actual methods are pretty much invisible 00:14:55.920 --> 00:14:56.919 to other participants, 00:14:56.920 --> 00:15:00.079 unless they already know that you're using Emacs. 00:15:00.080 --> 00:15:01.799 That's my talk. 00:15:01.800 --> 00:15:02.559 Thank you. 00:15:02.560 --> 00:15:07.320 You can find me on mastodon.social or on libera.chat.