KDE - changing the way you use Qubes

TL;DR: 1. Keyboard layout switching that works and preserves privacy; 2. Dynamically uncluttering the system tray in general (configurable).

Another one who appreciates Kubes OS here :wink:

I think most here know that there are a couple of bugs with KDE in dom0 that have not been fixed in years: keyboard layout switching does not propagate properly to any qube; and system tray icons based on Gtk3 are broken (invisible or white squares).

If we go deeper into Qubes OS keyboard layout switching and system trays in general though, and not just in KDE, there are things that can be improved:

  1. The current Qubes OS keyboard layout switching design, as I understand it, involves dom0 telling all qubes at the same time (and not just the one you’re currently using) to switch to the new keyboard layout (when it works, anyway). This seems to happen regardless of Layout Switching Policy in settings being per Application/Window/Desktop/Global, which doesn’t seem to change anything for qube windows (correct me if I’m wrong). Such a design is bad for fingerprinting, due to revealing to other untrusted qubes things like which languages you use and exactly when you use them, making a kind of a timing correlation side-channel. Even if eliminating all similar channels would be hard and outside of scope for Qubes OS, I’d argue this is among the worse ones, and moreover, revealing any of this is unnecessary. Relegating layout configuration and switching entirely to templates or qubes and away from dom0 would be one way to improve privacy (and it would work, unlike KDE&dom0).
  2. In Qubes OS we tend to get more system tray entries than in other OS, sometimes multiple instances of the same app, each from a different qube, for example:

It would be nice if there was a way to automatically hide some of the system tray entries when they are not needed, and show them again when they are. Like, hide entries that belong to qubes other than the one I’m currently using. It would reduce clutter and confusion (this would also help somewhat with broken icons).

The reason I’m bringing up 1 & 2 together is that solutions for both go well together.
My solutions/workarounds/hacks:

  1. (KDE or not) Install fcitx5 in each template where it’s needed and configure keyboard layouts/input methods and keyboard shortcuts in each qube where it’s needed separately. Apparently Fcitx5’s layout switching is not broken by Qubes OS’s layout switching (non-)integration, and it also has a working and visible system tray entry to indicate the current layout.
    In case of Fcitx5 not working with some of the apps or some other issue, remove it completely and install ibus instead. Beware that it’s based on Gtk3, so its systray icon is broken in KDE dom0, but you get a configurable layout/input method indicator in the center of the screen when pressing the keyboard shortcut for switching, which I think is good enough.
    Unless you want to be able to switch layouts for dom0 itself, you can disable them from System SettingsInput devicesKeyboardLayouts → delete the keyboard shortcuts you want to use in Fcitx5/IBus instead and uncheck Configure layouts.
  2. (KDE only) Using some ideas from other scripts, I put together something that does the job of automatically hiding&showing tray entries after manually specifying the names of qubes and tray entries to be shown with them. Yeah, it’s ugly, not the most convenient to set up initially, and won’t hide entries from [dispXXXX] reasonably, but at least for tray entries that can be specified you get a lot of control. If you want you can set up the simple “show only entries from the active qube” (or something more elaborate), except anything not specified in the script stays the way it’s configured in the System Tray Settings. The script works by toggling that very setting between the default Shown when relevant and Always hidden for the entries you want.

If you’re interested in this you can start by reviewing this JavaScript Plasma Desktop script, transferring it to ~/trayUpdate.js in dom0 (or typing it) and checking and configuring it in dom0 using nano ~/trayUpdate.js:

trayUpdate.js
// trayUpdate script by Stanley Qubrick, released in the public domain

// The name of the focused window's qube needs to be somehow provided as a variable called qubeFocused, such as by running a command like:
// qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "var qubeFocused = 'sys-net';$(< ~/trayUpdate.js)"
// to complete the script. Without a qubeFocused value this file is not a useful script.
//var qubeFocused = 'sys-net';
var qubeFocused;

// In trayEntries below you need to manually provide the names of qubes and the system tray entries to automatically hide.
// You must add a Window Action for all of these qubes so that their corresponding entries can also reappear when specified here.
// Add and edit lines in the following format as desired:
// ["qube1", ["[qube1] Fcitx5 Tray Window", "[qube1] Other app's tray ID", "Any other entry relevant to qube1 but not to some other qube",]],
// You can copy the names of system tray entries from ~/.config/plasma-org.kde.plasma.desktop-appletsrc if you've ever touched their setting.
// This script always respects the user's "Always shown" choice in the system tray configuration, but it needs to hijack the "Always hidden"
// setting for system tray entries included in any trayEntries value. You can omit an entry from trayEntries entirely to keep its setting.
const trayEntries = new Map([
    ["sys-net",    ["[sys-net] NetworkManager Applet",]],
    ["sys-whonix", ["[sys-whonix] Sdwdate",]],
    ["",           []], // qubeFocused='' for dom0 windows. You can use a generic value like 'show all' to cover multiple qubes or to do other things.
    //["show all",    ["[sys-net] NetworkManager Applet","[sys-whonix] Sdwdate",]],
]);

// This function is needed for handling the case of no "Always hidden" entries.
// https://stackoverflow.com/questions/5164883/the-confusion-about-the-split-function-of-javascript-with-an-empty-string/25597485#25597485
String.prototype.splitPlus = function(sep) {
    var a = this.split(sep);
    if (a[0] === "" && a.length === 1) return [];
    return a;
};

// Based on "Adding a widget to the System Tray" example script 2025 The KDE Community CC-BY-SA-4.0
// https://develop.kde.org/docs/plasma/scripting/examples/#adding-a-widget-to-the-system-tray
for (i = 0; i < panelIds.length; ++i) { //search through the panels
    panel = panelById(panelIds[i]);
    if (!panel) continue;
    for (tmpIndex = 0; tmpIndex < panel.widgetIds.length; tmpIndex ++) {
        appletWidget = panel.widgetById(panel.widgetIds[tmpIndex]);
        if (appletWidget.type == "org.kde.plasma.systemtray") {
            systemtrayId = appletWidget.readConfig("SystrayContainmentId");
            if (systemtrayId) {
                var systray = desktopById(systemtrayId);
                systray.currentConfigGroup = ["General"];
                var hiddenItems = systray.readConfig("hiddenItems"); // "Always hidden" entries in the system tray configuration.
                // Add together the "Always shown" entries and the ones specified for qubeFocused:
                var entriesToShow = systray.readConfig("shownItems").splitPlus(",").concat(trayEntries.get(qubeFocused));
                // Turn the current hiddenItems into an array; add all provided trayEntries; filter out the ones to show; remove duplicates:
                var entriesToHide = [...new Set(hiddenItems.splitPlus(",").concat(...trayEntries.values()).filter(e => !entriesToShow.includes(e)))];
                //print("\nentriesToHide =\t" + JSON.stringify(entriesToHide));
                if (hiddenItems !== entriesToHide.join()) { // Avoid unnecessary config write and reload
                    systray.writeConfig("hiddenItems", entriesToHide);
                    systray.reloadConfig();
                }
            }
        }
    }
}

Then you can create a single Window Action that executes a command whenever any window gets the focus from System SettingsShortcutsCustom Shortcuts → right click or EditNewWindow ActionCommand/URL → name it window focusTrigger → select Window gets focus → select Window simple: → on the right side click Edit... → under Window Types select NormalOKAction → as the Command/URL either type the following one-liner:

qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "var qubeFocused='$(xprop -id $(xdotool getwindowfocus) _QUBES_VMNAME|cut -d\" -f2 -s)';$(< ~/trayUpdate.js)"

Or, for easier review and modification, enter the path to a new Bash script with the following contents which do the same thing:

trayUpdateFocused.sh
#!/bin/bash

CUR_WIN_ID=$(xdotool getwindowfocus)
CUR_VM=$(xprop -id $CUR_WIN_ID _QUBES_VMNAME | cut --delimiter=\" --fields=2 --only-delimited)
# We start constructing a Plasma Desktop script (JavaScript) here as a way to pass the name of the focused window's qube to it:
PLASMA_SCRIPT="var qubeFocused='$CUR_VM';$(< ~/trayUpdate.js)"
# Documentation for running Plasma Desktop scripts: https://develop.kde.org/docs/plasma/scripting/#running-scripts
qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "$PLASMA_SCRIPT"

Tell me what you think about all this.

If other people here appreciate per-qube tray icons as I do, an obvious improvement goal would be to remove the need to type names and instead do the job for all existing tray entries belonging to qubes, but care must be taken if it involves parsing the entry name strings which come from untrusted qubes. Switching to an approach that does not touch user settings at all would be nice too, as would be supporting XFCE.

1 Like

Hello,

I recently updated to 4.3, and am loving the updated plasma, and unified notifications.
I wish to add audio to specific applications/qube’s notifications, but in application settings I can only see them as “other applications” and am unable to configure them.

Is it possible to add this functionality within dom0?

If not, is it possible to individually configure this inside the guest qube and detach from the centralized notifications while maintaining plasma styled notifications? I am unsure how to go about this from a minimal template.

Thank you for any assistance

I’m an inch away from fully switching to the KDE Desktop. The only remaining issue is keyboard layout switching.

Whenever someone mentions the keyboard layout switching problem in KDE, the usual response has always been, “Well, XFCE has the same issue too.” But now in Qubes OS 4.3 XFCE has no keyboard layout switching issues at all, so this really needs to be addressed in KDE.

Even with just two layouts, the keyboard still doesn’t switch properly in KDE. It was never this bad in XFCE.

If there’s any workaround, please let me know. I’ve already accepted the blank system tray icons issue, but this layout switching problem is practically making KDE unusable for many people like me.

1 Like

Are you looking for something like this Set your keyboard language in KDE debug 4.3 ?

edit : My bad it seems it’s not what you’re looking for. But i think we need a script in dom0 to fix the layout switching. Like when a user switch the keyboard layout then the script will execute setxkbmap (de)

I don’t know if it could work

Someone said that using sxhkd in every appVM will resolve the issue, but didn’t elaborate how to do it.

Why are the Blueman and Network Manager icons in the system tray white squares? If I understand this correctly the issue is from 2016. No one cares enough to fix this?
The system looks ugly and incomplete like that. Can you please do something about this issue?

2 Likes

Support here is a joke

There is no official support, people helping here are volunteers, as well as many contributors.

This issue seems to be not far from being solved. Did you test the suggested fix to help that?

1 Like

Learn to code.

1 Like

Agree.

I made a fix:

1 Like

That can be done using KDE’s own Custom Shortcuts (as long as it accepts the keyboard combinations you want to use) and borrowing techniques from other similar scripts (see this thread). The simpler way is to ditch other unreliable layout switchers and have a separate global shortcut for switching to each keyboard layout, and it is arguably better than having a single toggle shortcut, in many cases. The scripts can get the active window’s qube’s name like in my previous post here and then execute:

qvm-run $CUR_VM "setxkbmap de"

or better yet this line, because qvm-run has some weirdly huge added latency, which may be noticeable and problematic in a use case such as this:

qrexec-client -e -d $CUR_VM user:"setxkbmap de"

I haven’t tested this whole idea though.

I’ve myself given up on Fcitx5/IBus due to their flawed ways of detecting keyboard shortcuts and doing the layout switch and I’ve transitioned to sxhkd (in templates), which responds to key events reliably like KDE’s Shortcuts, but it’s more flexible with keyboard combinations, and it calls setxkbmap only for switching (rationale here at point 1 and instructions).

So far KDE has been pretty good, but i’m on an old machine with 16gb of ram and dom0 is struggling with kwinx11 and ram (even when I put it up to 4gb). Are there any tweaks that would cut that down a bit?

Edit: solution below


Question:

I am on Q4.3.1 with X11 KDE. I have removed the Qubes menu icon from the task bar out of curiosity and now there doesn’t seem to be a way to restore it. I use KDE’s application launcher now, which is decent, but I would like to get the original Qubes launcher back nevertheless.

I expect the Qubes launcher to be visible in the Widgets menu when editing the task bar (right click → “Add or Manage Widgets…”), just like the KDE’s application launchers. But it’s not there.

My 55xfce-qubes.sh is:

#!/usr/bin/sh

# Use Qubes provided menu instead of default XFCE one
XDG_MENU_PREFIX="qubes-"
export XDG_MENU_PREFIX

Which seems to be ignored because echo $XDG_MENU_PREFIX yields plasma-.

Help is appreciated, and until then: heed the warning – don’t remove the Qubes icon from your task bar :wink: :wink:


Solution:

In a file manager in dom0, navigate to /usr/share/applications, locate open-qubes-app-menu.desktop, and drag it onto the task bar. This will restore the original Qubes application launcher.

You use standard KDE method.
I have desktop file at .local/share/applications/net.local.qubes-app-menu.desktop

[Desktop Entry]
Exec=/usr/bin/qubes-app-menu
Name=qubes-app-menu
NoDisplay=true
StartupNotify=false
Type=Application
X-KDE-GlobalAccel-CommandShortcut=true

Open Thunar, locate file, drag it to space on panel. Done.

The launcher doesnt have icon - if you want to change this:
Right Click on icon and select Properties.
Click on the icon
Change Scope to All, and enter Qubes in search bar
Select Qubes-logo
Click OK
Click OK in Properties window.

Longer to type and read than to do.

I never presume to speak for the Qubes team.
When I comment in the Forum I speak for myself.

1 Like