Blog

Back

This page stores technical & other notes that I write. Expect the currently crude layout of the webpage to change as I experiment with new approaches to blogging.

Table of Contents

2025

2025-03-01 Saturday

Fixed ido completion in org-mode

I was trying to enable ido-completing-read in org-mode following norang's guide, but I couldn't get it to work. Setting the variable org-completion-use-ido to true was supposed to make org-mode pick the right completion mode, but I still got regular completions.

I noticed that org-completion-use-ido was not documented, which was strange. Searching on the Internet, I discovered that this variable was removed in org-mode version 9.0, and that ido now uses plain completing-read. It looks like ido-completing-read+ (formerly ido-ubiquitous) can help me achieve the same kind of functionality, though. [2025-03-01 Sat 13:21]

norang.ca org-capture template for habits doesn't work out of the box

While learning norang's excellent org-mode setup, I tried to test out org-habit by creating a habit using C-c c h. To my dismay, the resultant habit would display neither in the main agenda view (F12 SPC), nor would it show up in the habit view (F12 h). I was puzzled for quite a while, but I figured it out through trial and error.

The issue lies in norang's capture template for habits. Its structure is as follows:

"* NEXT %?\n%U\n%a\nSCHEDULED: %(format-time-string \"%<<%Y-%m-%d %a .+1d/3d>>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n"

which translates to:

  • the literal: * NEXT
  • %?: the cursor is placed here
  • %U: inactive date and timestamp
  • %a: annotation, normally the link created w/ 'org-store-link'
  • the SCHEDULED: timestamp, in the format as prescribed by org-habit
  • the :PROPERTIES: section, containing fields prescribed by org-habit

Example:

* NEXT Get up at 6AM
SCHEDULED: <2025-03-01 Sat .+1d/3d>
[2025-03-01 Sat 15:21]
norang.ca org-capture template for habits doesn't work out of the box
:PROPERTIES:
:STYLE: habit
:REPEAT_TO_STATE: NEXT
:END:

Turns out, there cannot be any content between the initial org heading and the :PROPERTIES: entry (excluding SCHEDULED:). If there is, then the whole heading is not recognized as a habit. Placing %U and %a in between caused org-habit to fail to recognize this.

The fix moves the placeholders to the bottom:

"* NEXT %?\nSCHEDULED: %(format-time-string \"%<<%Y-%m-%d %a .+1d/3d>>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n%U\n%a\n"

The result:

* NEXT Get up at 6AM
SCHEDULED: <2025-03-01 Sat .+1d/3d>
:PROPERTIES:
:STYLE:    habit
:REPEAT_TO_STATE: NEXT
:END:
[2025-03-01 Sat 15:21]
norang.ca org-capture template for habits doesn't work out of the box

[2025-03-01 Sat 15:05]

Useful emacs features

  • in org-mode, C-c C-e h o to export to HTML and open
  • in org-mode, i <s TAB to insert a special block

[2025-03-01 Sat 15:39]

2025-03-02 Sunday

Emacs Lisp can hold both variable & function values at the same time

https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Components.html

A symbol can be both a function and a variable at the same time.

(setq magic "abracadabra... ")
(defun magic () "tada!!!")

(concat magic (magic)) ; "abracadabra... tada!!!"

[2025-03-02 Sun 15:01]

C-0 C-c c to org-capture under your current location.

Useful for ensuring that the clock is started at all times, including when extending an existing project.

[2025-03-02 Sun 20:28] Publish everything using emacs

Use org-startup-folded 'content to only show outline of org buffer

The documentation for this function is awkward. The correct way to configure it is:

(setq org-startup-folded 'content)

and not

(setq org-startup-folded "content")

or anything equally plausible.

[2025-03-02 Sun 16:14] file:///home/igrom/.emacs.d/init.el#org75ce5f8

2025-03-26 Tuesday

Sandboxing WeChat on Linux, gksudo vs pkexec

WeChat is the de-facto instant messenger in the People's Republic of China, and it's not easy to avoid it. However, it is well-known that it conducts different kinds of snooping activities, including fingerprinting files on your device. I wouldn't put other activities, such as keylogging, past it. It has to be said that the user experience is miles better than Messenger and WhatsApp, though.

There exist Docker images to run WeChat on Linux. Let's have a look at the privileges given to the container. The following is taken from the project's README.md file, with my emphasis:

  docker run \
    --name DoChat \
    --rm \
    -i \
    \
    -v "$HOME/DoChat/WeChat Files/":'/home/user/WeChat Files/' \
    -v "$HOME/DoChat/Applcation Data":'/home/user/.wine/drive_c/users/user/Application Data/' \
#1  -v /tmp/.X11-unix:/tmp/.X11-unix \                                                                
#2  -v "/run/user/$(id -u)/pulse":"/run/pulse" \                                                      
    \
#3  -e DISPLAY \                                                                                      
    \
    -e XMODIFIERS=@im=fcitx \
    -e GTK_IM_MODULE=fcitx \
    -e QT_IM_MODULE=fcitx \
    -e GID="$(id -g)" \
    -e UID="$(id -u)" \
    \
#4  --ipc=host \                                                                                      
#5  --privileged \                                                                                    
    \
    zixia/wechat

Explanation of the emphasized lines:

1. and 3. Access to the X11 socket permits WeChat to run as an X client application and display a window in your X environment. Since access to the socket is either none or absolute, that also grants it unfettered access to your input devices. It might read information about your X environment and log your keystrokes even if you're not currently focusing WeChat's window.

2. Access to the PulseAudio socket allows WeChat to play back and record sound. I'm worried about it starting a surreptitious recording, and would rather disable sound entirely.

4. This prevents Docker from creating a private SystemV IPC namespace for WeChat; as a result, WeChat can communicate with other processes or access some shared information. See here for the description of the setting and here for more information about the vulnerability.

5. With –privileged, you're pretty much granting the container root access to your host machine. If that isn't handing over the keys to the kingdom, then I don't know what is.

All together, it would've already been considered a risky setup for any containerized software coming from a third-party vendor. For software with known characteristics of malware, it is mad.

Instead, we can use x11docker to run WeChat in a more secure manner. x11docker sets up a second X11 server acting as a relay. WeChat renders to the relay server, while the relay server renders to the original X sever as a single window. WeChat has no access to the original X environment — consequently, it cannot eavesdrop on anything — nor does it run in the host operating system's various namespaces.

Here's how to achieve it:

#! /bin/bash
pkexec /usr/bin/x11docker --desktop --clipboard=superv --pulseaudio --init=systemd --network --home="/home/igrom/Documents/wechat" -- --hostname=Windows --cap-add=IPC_LOCK x11docker-deepin-wine

Note about gksudo and pkexec: gksudo is deprecated, as it is unmaintained and not capable of supporting fine-grained permissioning. Instead, one can use pkexec from the polkit project.

However, there's a catch:

In addition the PKEXEC_UID environment variable is set to the user id of the process invoking pkexec. As a result, pkexec will not by default allow you to run X11 applications as another user since the $DISPLAY and $XAUTHORITY environment variables are not set. These two variables will be retained if the org.freedesktop.policykit.exec.allow_gui annotation on an action is set to a nonempty value; this is discouraged, though, and should only be used for legacy programs.

In order to use pkexec to run x11docker, a graphical application, we have to create a corresponding policy. Here is an example policy:

# /usr/share/polkit-1/actions/x11docker.policy

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
 "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
    <action id="org.freedesktop.policykit.pkexec.x11docker">
    <description>Run x11docker program</description>
    <message>Authentication is required to run x11docker</message>
    <icon_name>accessories-text-editor</icon_name>
    <defaults>
        <allow_any>auth_admin</allow_any>
        <allow_inactive>auth_admin</allow_inactive>
        <allow_active>auth_admin</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/x11docker</annotate>
    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
    </action>
</policyconfig>

This allows us to run x11docker/WeChat from a .desktop file. Neat, huh? [2025-03-26 Wed 23:12]

Created: 2025-03-28 Fri 00:44

Validate