Programming approaches to Alternative Appmenu icon effects, Setting default workspace per qube, Additional label colors

tl;dr:

This is a work in progress. qubes-label is renamed to qubes-label-tt and qvm-appmenus-tweak-tools is renamed to qvm-appmenus-tt. Once our job is done, Independent and proper community guidelines will be posted with references to this thread. Please read the entire thread for more information.

Original thread:

I have been working on a tool to create additional custom labels and colors for Qubes OS. So far, I have created a rapid prototype to manage labels in Qubes OS database to analyze effect of new labels on behaviour of different GUI tools. Here is the output of this tool with --help option:

This tool is a simple command line utility to manage Qubes OS labels. It could
list, create, get value, print index or remove labels from Qubes OS database.
In order to avoid possible conflicts with any probable official labels which 
might be introduced in the future, it is advisable to prepend a suffix to new
custom labels. Good examples are 'custom', 'user', 'personal', etc. 
Also never ever remove standard labels!

usage: qubes-label [--verbose] [-assume-yes] [--help] [--ANSI] COMMAND ...

options:
  -v, --verbose             verbose operation
  -h, --help                show command help
  -y, --assume-yes          automatically answer yes to all questions
  --ANSI                    print label values in color with ANSI X3.64
                            (ISO/IEC 6429) escape codes in terminal. it requires
                            color capable tty such as xterm or xfce4-terminal
  --raw-data                output data in easy to parse format without headers
                            intended for bash-parsing. this will disable ANSI &
                            verbose options.

subcommands:
   list                     List all labels and their values
   create <LABEL> <VALUE>   Create a new label with the provided color value.
                            Value should be in '0xRRGGBB' format.
   get <LABEL|INDEX>        Print hexadecimal value of label
   index <LABEL>            Print index of the label in Qubes database
   remove <LABEL|INDEX>     Remove label from Qubes database.

My initial findings are as follow:

  1. Calling admin.label.* API functions via qubesd-query is on the slow side. I did not try to switch to Python at the moment since I wanted to keep this tool as a pure bash script for the time. However, 413ms for each admin.label.Get call is not very impressive (neither end of the world). Even on this old i5-4300u based laptop. To reproduce: time for 1 in $(seq 0 9); do qubesd-query dom0 admin.label.Get dom0 red --empty > /dev/null;done
    I am not aware if there is any better alternative to qubesd-query for Admin API calls in bash. I have asked before on forum but received no feedback.
  2. I wonder if any input sanitation is performed at API side. Such as SQL injection protection. Or whether clients should implement it. If anyone has information on this, please inform me.
  3. I did not find any information on maximum label string length or allowed characters.
  4. API has some protection against user error. For example you could not delete a label if it is used by a Qube.
  5. You could inquire admin.label.Get with both label name and its Index. I believe this is not documented.
  6. After creating the label, the necessary png/svg files has to generated and copied to /usr/share/icons/hicolor folder. I wonder if ~/.local/share/icons/hicolor/ would be a viable alternative. Since even the former location is not fully functional (see next points).
  7. Generating all PNG/SVG files from one or more source SVG files is easy, if ImageMagick is installed.
  8. Some GUI tools work perfectly with custom labels and icons. The old Qubes Manager works fine.
  9. Even if you replicate all and every png/svg of existing label for your new custom label, some GUI tools would still fail. I wonder if this is because of hard-coded labels in such tools, or there are something else beside API DB and icons that I am missing. If you set a new label for any Qube, Qubes Domains tray widget (qui-domains) goes to a restart loop on next login. qubes-app-menu is another GUI widget which does not recognize custom labels. Investigating these tools is the next logical step
  10. Reusing existing Qubes OS icons should be OK as they are shared with CC-BY-SA license under qubes-artwork Github repository.
  11. Using Distro Logos (e.g. Debian’s, Fedora’s, Arch, …) should be OK as long as it is allowed by the their copyright guides. I tried a custom debian label with 0xd70a53 color and Debian logo. I would like this as an alternative to the current template icons.

I am trying to look beyond this and explore other possible options. There are many open or closed issues on Github with constructive feedback from users and the Qubes team. Some of them are relatively new and some are really old (over two years). I would really like to know if the team is actively working on this in parallel with a viable outcome in short term.

It would be very nice if a custom property/feature could be added to domains for effect style. Similar to what we currently have for tray icons (overlayed using Alpha channel, thin/thick borders, tint and untoched). An alternative to qvm-get-image and qvm-get-tinted-image and improved qubesimgconvert library.

A custom property/feature for domains to open their Windows in specific Workspaces would be very nice. This could be done via readily available tools such as devilspice(1). And each workspace could have their own individual background. Nice colored backgrounds are already made by the UI/UX team.

3 Likes

This is so awesome!
Thank you
:pray:t4:

1 Like

Update:

I did some minor work on Additional Labels and options to signify VM ownership of windows/widgets/functionality, other than color ideas. I studied Github issues and pending tasks which are currently being worked on by the team, answering some of my own questions in the previous post.

Launching Applications in Workspaces with matching label

This scenario turns out to be extremely easy to implement.
0. User could easily create their own workspaces with matching label names (red, orange, yellow, …) and set the unique background matching label color. This process could be automated with xfconf-query. Qubes provided themes in “/usr/share/backgrounds/qubes” are more than adequate.

  1. We have wmctrl(1) already installed in dom0 (most probably on dedicated GUI Qube). And while we are still on X11 and no sign of Wayland in near future, we could use wmctrl to switch to the workspace dedicated to label color with wmctrl -s and then run the app with qvm-run(1).
  2. Of course qvm-run(1) alone could not do the above at this time. And we would like to avoid touching qvm-appmenus(1). But we could easily modify ~/.local/share/applications/org.qubes-os.vm.*.desktop files. And they can be easily regenerated, reverting to the default status.
  3. I have to see if there is a hook for qvm-appmenu to automate the process.
  4. Another idea is a to open new App Windows in Workspaces matching Qube Name.
  5. Another way to implement this would be a custom tag/pref for Qube (e.g default-workspace). Unfortunately there is no any admin.customtag.add or similar feature in the API. But there are workarounds which are not invasive.
  6. wmctrl is pretty safe. It will ignore missing workspaces and user mistakes.

I will implement this next as it is the least invasive method and pretty easy to implement. And I like the idea for my personal use. Any feedback is appreciated. Specially if anyone has already implemented this, so I could avoid reinventing the wheel.

1 Like

Launching Applications in Workspaces with matching label (continued).

You could easily modify .desktop files with sed using regex. Let’s say you always want applications belonging to personal qube to open in 3rd workspace and switch to that workspace. Do this:

sed ~/.local/share/applications/org.qubes-os.com.*personal*.desktop -i -e 's/\(Exec=qvm-run\)\(.*\)/Exec=sh -c \"wmctrl -s 2;qvm-run\2\"/'

wmctrl -s 2 since Workspace indexes start at 0
To revert to original .desktop files:

qvm-appmenus --update --force personal

Other approach: adding custom feature to Qube for default workspace. Something like qvm-features qube custom-workspace workspacenumber

This is so simple that almost does not require any special custom tool or community guide. And no need for (discontinued) devilspie or any other weak dependency. Just leaving this here for anyone who needs it. I will spend time on more label (colors) and effects.

1 Like

Moderation note: I moved the topic to the General discussion category that seems better suited than Feedback since the topic contains work in progress. Great thread so far @alimirjamali !

1 Like

I spent more time and worked upon the default ‘tint’ effect which has served us well since 2013. I made a rapid prototype in Python. Here is the output of qvm-get-filtered-image --help which I have created:

usage: qvm-get-filtered-image [-h] [--ANSI]
                              [--filter {custom,tint,overlay,thin-border,thick-border,untouched,invert}]
                              [--mirror {vertical,vertically,horizontal,horizontally,both}]
                              VMNAME COLOUR SRC DST

Secure copy of images between virtual machines

positional arguments:
  VMNAME                Source VM
  COLOUR                Colour
  SRC                   Path inside source VM
  DST                   Destination path in this VM

options:
  -h, --help            show this help message and exit
  --ANSI                Print ANSI X3.64 (ISO/IEC 6429) color representation
                        of image in color capable tty
  --filter {custom,tint,overlay,thin-border,thick-border,untouched,invert}
                        Filter to perform on the image. 'custom' is the
                        default i.e.: Program will look for 'imgfilter' in
                        qube features. If that feature exits, its value should
                        indicate default filter for that qube. If 'imgfilter'
                        is missing or it contains an invalid filter, 'tint'
                        will be the default.
  --mirror {vertical,vertically,horizontal,horizontally,both}
                        Mirror image in one or both axes.

Both SRC and DST may specify format in gm(1) way, i.e. png:aqq.gif

The original qvm-get-tinted-image could be found on qubes-app-linux-img-converter repository. But most of the work is done within qubesimgconverter library, Image class and tint method. Which is resides in qubes-linux-utils repository.

Creating a child class of qubesimgconverter.Image class and adding custom overlay, border, invert, mirror, untoched and other filters is easy. I also added a ANSI method to be able to print image representation in terminal, eliminating requirement for ristretto or any image viewer to rapidly check output. Flipping icons is also possible. But I guess no one wants a qube with mirrored icons. By default, this tool checks for a imgfilter feature of source qube which user could easily set via qvm-features. And apply that effect instead of the default tint filter. Otherwise it behaves exactly like qvm-get-tinted-image. Some screenshots:







Once this is finished, I will use the untouched icons for my own personal qube. And the invert icons for a paranoid qube.

The only remaining job is to work on qubesappmenus library, Appmenus class and appicons_create method which resides within qubes-desktop-linux-common repository. And it will be done. Hopefully tomorrow. Individual tools could be easily made without performing invasive surgeries on the original tools and libraries.

4 Likes

I was busy yesterday but had some free time today to work on my personal project of alternative effects to tint for Appmenu icons. The outcome is called qvm-appmenus-tweak-tools. It has the exact syntax as qvm-appmenus(1). It will check if imgfilter feature is set for qube and could perform overlay, thin-border, thick-border, untouched, invert, flip, mirror effects in addition to the default tint. Individual qubesimgconvertertweaks and qubesappmenustweaks libraries and a Makefile with install target which would install executables and libraries at ~/bin and ~/.local/lib directories is also available. Do NOT use if you could not read and understand the Python code. And definitely not on a production system. It could work as a drop alternative to qvm-appmenus which should make the effects stable. Otherwise qvm-appmenus reverts to the original tint effect every time it is invoked.

Usage:

qvm-features VM imgfilter <tint|overlay|thin-border|thick-border|untouched|invert|mirror|flip>
qvm-appmenus-tweak-tools VM --update --force

To revert back to the original tint effect:

qvm-features VM imgfilter --unset
qvm-appmenus VM --update --force

Some screenshots:
Original tint effect:

Overlay which turns out to be nice with some label colors:

Thin border

Thick border

Untouched which I will eventually use for my personal trusted qube

Invert effect which I will use for my untrusted paranoid qubes

Mirrored icons which I find useless (pay attention to bluetooth icon

Flipped icons which I find again useless (pay attention to Accessibility Icon)

With these effects, I will have 8 labels * 4 effects + 1 untouched + 1 inverted = 34 distinguishable icons. But this is start of work. Icons on Appmenu do not reflect Qubes OS behaviour on systray icon effect which is still set per whole system rather than per qube. I have ideas on how to implement it without performing surgical invasive operation on the operating system. Hopefully via Freedesktop features and using such beautiful CSS effects.

And while I am at it, I will add ability to set a default workspace per qube feature to qvm-appmenus-tweak-tools. But this is only the start the work. This whole thread started based on the idea of custom label colors. It appears that the UI/UX team do not approve many colors because of very legitimate reasons. I had the opportunity to read their comments on related Github issues. What I hope that everyone could agree upon would be that the option should be always available when the necessity arises. The hard part of the work is not the programming. It is the ability to write a readable code worth of peer review and highly in demand, then properly communicate it with the small and overloaded team without wasting anyones time.

P.S.: To the moderation:
I guess I should rename the thread title to something else? Maybe “Programming approach to Alternative Appmenu icon effects, Setting default workspace per qube, Additional label colors”

2 Likes

Definitely impressive work!

1 Like

OK. Back to the original work on custom color labels. Fortunately the issue turns out to be simple and covered before on the forum in this thread:

The only remaining work would be icon generation. My original idea was to write a complete custom icon generator which could get an SVG as input, tint it with color, then use GraphicMagick or ImageMagick to generate pngs from that. Or even the ability of accept 5 different icons for appvm, dispvm, servicevm, standalonevm and templatevm which would be subsequently used by qubes-app-menu and other GUI tools. The other idea was to generate my own artwork from my tool. But I am not a UI/UX person and whatever I sketch would most probably look horrible.

Back to the tools suggested in that forum thread designed by Willy-JL. Seperate tools for adding and removing colors. However qubes-color-del is a mix of bash and python code. And I do not want to switch to python or write a mixed tool. Time to flex my bash scripting muscles and do it purely in bash. One more thing to due would be renaming qubes-label to something which would never conflict with future official tools. Something like qubes-label-tweak-tools would be better.
Finally I have to decide if I want to add a GUI to add/delete/view color labels. PyQt5 is nicely provided by Qubes OS. I had little exposure to Qt long time ago. But still much better than tkinter which I have never touched and neither is present. I have to decide if I should spend time and make such a tool as the CLI one is more than enough for my personal use. Or spend time on more fun projects.

2 Likes

Those Willy JL tools already apply tint, albeit to only the standard Qube icons. There’s no reason, however, they couldn’t work on other icons. The bad news is that for them to work you must install imagemagick in dom0, just to use the convert utility he calls to convert RGB to HSV and back again. (This could probably be replaced with bash code if someone is ambitious enough.)

He essentially converts the RGB values for the orange icons to HSV, adjusts the hue, then converts back.

We know, of course, that Qubes already does this on the fly with other icons, which is why Firefox (for instance) gets colorized red, or blue, on my system.

1 Like

The bad news is that for them to work you must install imagemagick in dom0

GraphicMagick might be preinstalled. As there were some hints about switching from ImageMagick to GraphicMagick in the official codes. But I have to double check.

(This could probably be replaced with bash code if someone is ambitious enough.)

It should be possible with awk, sed and other tools as they are nicely provided by default. And the SVG format is easy to interpret XML format.

We know, of course, that Qubes already does this on the fly with other icons, which is why Firefox (for instance) gets colorized red, or blue, on my system.

Qubes uses custom Python code using NumPy library. Source here. I have been working on other effects & UI/UX improvements. Details are available in previous posts. I renamed my qubes-label to qvm-tweak-tools and qubes-label-tweak-tool to qvm-appmenus-tweak-tool. Sources available here.

Feel free to rename the topic.

Once you’ve got enough to write a tutorial about how to install and use the tools you’re writing, you could also open a new topic in the Community Guides category and link to this one for context. Up to you!

3 Likes

Thanks for the reply.

I believe I can not do that personally. It appears that the edit option is not available for my early posts. I am not sure if the forum software hides edit option after a certain period.

Let me know the new title, and I or another moderator will apply it :slightly_smiling_face: (there is a time limit for edition that goes away after you reach a given trust level in the forum, that’s regular Discourse behaviour).

So I did a quick analysis of the colors used for the modern Qute Icons used in the Qubes OS 4.1/4.2 menus and designed by a professional UI/UX team. And I am happy that I implemented --raw-data qube-label-tweak-tool

Here is the result:

[alimirjamali@dom0 ~]$ for record in $(qubes-label-tweak-tool list --raw-data); do label="${record%%\|*}";value="${record##*\|}";echo "${label} label = ${value} official Qubes OS qute icons use these fills:";grep /usr/share/icons/hicolor/scalable/apps/*vm-${label}.svg -e 'fill="#' | sed 's/\(.*fill=.\)\(#\([0-9a-fA-F]\)\{6\}\).*/\2/g' | sort | uniq; done
red label = 0xcc0000 official Qubes OS qute icons use these fills:
#64120F
#641312
#D42C27
#D62821
orange label = 0xf57900 official Qubes OS qute icons use these fills:
#753813
#E96F24
yellow label = 0xedd400 official Qubes OS qute icons use these fills:
#946705
#EFBF0A
green label = 0x73d216 official Qubes OS qute icons use these fills:
#325830
#5ABC57
gray label = 0x555555 official Qubes OS qute icons use these fills:
#34373A
#3B3B3B
#A2A1A1
#B4BBC1
#C4CACF
blue label = 0x3465a4 official Qubes OS qute icons use these fills:
#0D2377
#0E2276
#4488DF
purple label = 0x75507b official Qubes OS qute icons use these fills:
#3F0C46
#A23EB2
black label = 0x000000 official Qubes OS qute icons use these fills:
#000000
#3B3B3B
#585858
#605F5F
#FFFFFF

It is really interesting that the UI/UX team had to use 2 colors for orange, yellow, green and purple; 3 colors for blue; 4 colors for red and 5 colors for gray and black icons. I guess you should be a color scientist or a UI/UX person to properly understand the concepts. But I believe that unlike Willy-JL selection of purple as the base template, I should chose black or gray.

p.s.: Of course tint does not like the gray scale templates. Complicated calculations would be needed. Switching to red.

1 Like

I really appreciate if you could rename the title to:

Programming approaches to Alternative Appmenu icon effects, Setting default workspace per qube, Additional label colors

or if it is too long:

Alternate Appmenu icon effects, default workspace per qube, More labels
1 Like

Yeah, I have no idea why he picked orange to start with.

Please be aware (if you haven’t noticed already) that the color you provide on the command line to his script is NOT the exact same saturation/value the script does; it applies some sort of multiplier. Ideally, we’d know what color should be supplied to the script to recreate the qube icons already in use, for reproducibility.

1 Like

Yes. Unfortunately xfce4-ternimal is capable of only 256 colors. It is not possible to represent the full 16.7 million colors in the terminal. ANSI escape codes could only represent the nearest color. But you are absolutely right and I have to add clarification to the qubes-label-tweak-tool help about this limitation.

p.s.: Once my work with CLI tools is done, I will try to work on GUI tools. I will use the QColorDialog widget. It uses xfce4 default color picker which is kinda ugly but hopefully should do the job.


1 Like

Progress report on qubes-label-tweak-tool:

I wrote all of the rgb_to_hsv, hsv_to_rgb and tint functions in pure bash. It was a challenge since bash does not support floating point math and I wanted to avoid Python, bc or other dependencies. Minor precision sacrifice will be made. But this should be negligible (around 0.4%).

It appears that all of the Qubes GUI tools will work fine if the new icons are copied to ~/.local/share/icons/hicolor rather than /usr/share/icons/hicolor. This would eliminate requirement for sudo. I have to do more tests to confirm this :white_check_mark: (needs some work. most probably possible).

1 Like

This is so cool thank you!

:smiley:

1 Like