Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre desktop (publicaciones antiguas, página 1)

Desktop setup


I am a long-term KDE us­er. How long ter­m? Well, since 1997 or so with in­ter­mit­ten­cies. A cou­ple of weeks ago, I switched my per­son­al desk­tops to QTile.

Manda­to­ry screen­shot:

A desktop


Well, I like to switch things around ev­ery few years. I have used Uni­ty, and MATE, and even LxQt at some point, and I have no­ticed over the years that I don't tend to over­lap win­dows, so tiling win­dow man­agers are the nat­u­ral pro­gres­sion of my us­age.

For a few years I have used Krohnkite an awe­some KWin ex­ten­sion that has re­al­ly been a plea­sure to use and proved me that a tiling WM, with a few rea­son­able key­board short­cut­s, was a work­able so­lu­tion.

Late­ly I have been build­ing a home­brew lap­top which has fair­ly lim­it­ed hard­ware, but I want to use for re­al. So I al­so want­ed to ex­plore ways to low­er re­source us­age.

Oth­er re­lat­ed con­cern­s:

  • I have very dy­nam­ic mon­i­tor con­fig­u­ra­tions. My com­put­ers gain and lose mon­i­tor all the time, and this needs to be han­dled au­to­mat­i­cal­ly.
  • I have mul­ti­ple com­put­ers (work, home, home­brew) and they all have very dif­fer­ent set­ups and con­fig­u­ra­tions, but I want them all to work the same.
  • I use chez­moi to man­age my con­fig­u­ra­tions so I want con­fig to be sim­ple text files I can store with a min­i­mum of tem­plat­ing.
  • I want com­fort. I want disk au­to­moun­ing, vol­ume keys, blue­tooth menus, wifi con­fig­u­ra­tion, a clock, bat­tery in­for­ma­tion, no­ti­fi­ca­tions and so on.

But why QTile specif­i­cal­ly:

  • It's tiling but with a nice at­ti­tude. The whole "hard­core" thing in both tiling WM users and projects is a bit tire­some.
  • It's writ­ten, con­fig­urable and ex­tend­able in Python, which I like.
  • It works rea­son­ably out of the box. No, a black screen where you can do noth­ing with­out look­ing up short­cuts in your phone at first is too much.
  • It's "dy­nam­ic". This is one of those minute sub­cat­e­gories you can see in WM fan­dom, but ba­si­cal­ly: win­dows get placed more or less cor­rect­ly by de­fault, while oth­er WMs will make you ex­plic­it­ly han­dle each win­dow as it ap­pears, which sounds sort of like tor­ture to me.

So what?

So I will now de­scribe painstak­ing­ly ev­ery de­ci­sion I made as of to­day, and de­scribe the im­por­tant con­fig­u­ra­tion, and bore any­one who tries to read this to tears, that's what.

In an at­tempt to make this a bit less an­noy­ing I will set­up a prob­lem, then de­scribe the so­lu­tion I found.

Uniform UI for utilities

The Problem

There are a num­ber of ways you in­ter­act with your "desk­top". You may want to lo­gout. Or start an ap­p. Or run a com­mand. Or con­fig­ure a blue­tooth speak­er. Or see the clip­board his­to­ry. Or con­fig­ure wifi.

In the desk­top world, this all comes in­clud­ed in the pack­age deal. In the Win­dow Man­ag­er uni­verse, you have to roll your own, and most set­ups end with a dis­parate col­lec­tion of util­i­ties, like blue­man and net­work-­man­ag­er and clip­it and so on plus what­ev­er the WM it­self pro­vides.

Well, but what if they could be the same thing?

What if in ad­di­tion they could all share a love­ly, cus­tom­iz­a­ble UI?

The Solution

En­ter rofi

the most com­mon us­age for rofi is as an app launcher, and it's great at that, but it's just scratch­ing the sur­face:

rofi as launcher

Be­cause of its flex­i­ble ar­chi­tec­ture, it can be used to con­fig­ure your net­work us­ing net­work­man­ager-d­menu:

rofi as network manager

As your pow­er/l­o­gout menu via rofi-pow­er-­menu

rofi as power menu

And much more. I al­so use it as a front­ed to a pas­word man­ag­er, a fron­tend to ssh, a sim­ple To­do list, an emo­ji pick­er, as a fan­cy win­dow switcher, and as a clip­board his­to­ry man­ag­er us­ing rofi-­green­clip

rofi as clipboard manager

Rofi starts so fast that it's of­ten im­posi­ble to no­tice the dif­fer­ence be­tween hav­ing a tool al­ways run­ning and with an icon in the systray and just hav­ing a but­ton that launch­es rofi.

So, how do I use it in my ~/.config/qtile/

Bound to some key short­cut­s:

keys = [
    # Launch things
    Key([mod], 'p', lazy.spawn('rofi -show drun'), desc="Run app"),
    Key([mod, "shift"], 'p', lazy.spawn('rofi -show run'), desc="Run Command"),
    Key([mod], 's', lazy.spawn('rofi -show ssh'), desc="Ssh"),
    Key([mod], 'e', lazy.spawn('rofi -show emoji'), desc="Emoji"),
    Key([mod], 'v', lazy.spawn('rofi -modi "clipboard:greenclip print" -show'), desc="Clipboard")
    Key([mod, alt], "Tab", lazy.spawn('rofi -show window'), desc="Move focus to next window"),

I al­so added a Launch­Bar wid­get to my QTile bar where it re­places some­thing like clip­it, the blue­man ap­plet, a pass­word man­ag­er and a to­do ap­p:

    widget.LaunchBar(padding=0, text_only=True, font="Font Awesome 6 Free", fontsize=16, foreground="2e3440", progs=[
        ("", "rofi-bluetooth", "Bluetooth"),
        ("", "rofi -modi 'clipboard:greenclip print' -show", "Clipboard History"),
        ("", "rofi-pass", "Passwords"),
        ("", "rofi-todo -f /home/ralsina/todo.txt", "Todo"),
        ("", "flameshot gui", "Screenshot"),

The first field that prob­a­bly looks like a square in there are uni­code char­ac­ters dis­played on the desk­top us­ing font awe­some:

launchbar that uss rofi

Al­so for mouse in­ter­ac­tions with the Wlan wid­get:

widget.Wlan(format=" {percent:2.0%}",width=54, mouse_callbacks={'Button1': lazy.spawn('networkmanager_dmenu')}),

I even use it to show me the short­cut list in case I for­got any!

rofi showing shortcuts

I could write some mi­nor code and use it for oth­er things too. Rofi is a mag­nif­i­cent ex­am­ple of a tool with a nice API that you can lever­age to make it do many dif­fer­ent things.

Display Configuration

The Problem

My dis­play con­fig­u­ra­tions are many. I use note­book­s, so they all have one "de­fault" con­fig­u­ra­tion where they use their own screen.

In one case, it's all it can use.

In an­oth­er, it's per­ma­nent­ly docked to a mon­i­tor above its screen, but some­times I close the note­book and the on­ly dis­play is the mon­i­tor.

In an­oth­er it's usu­al­ly docked to a mon­i­tor be­sides its screen, but it's shared with my work com­put­er, so it los­es and re­cov­ers that mon­i­tor dozens of times via a HD­MI switch through the day as I switch tasks.

While QTile han­dles grace­ful­ly the ad­di­tion and re­moval of dis­plays in gen­er­al, there are some is­sues.

  • Us­ing the HD­MI switch did­n't make the mon­i­tor "go away" which caused some is­sues with bar­ri­er
  • The con­fig file de­scribes the "bars" for each screen. So I need to put the main bar that has the systray on a screen that is al­ways on. But the screens are one per-out­put and in a ma­chine-de­pen­dent or­der, and things got com­pli­cat­ed re­al­ly quick. Here Plas­ma does the right thing ef­fort­less­ly.

The Solution

En­ter au­toran­dr an awe­some tool that will re­act to changes in your sit­u­a­tion and do the right thing.


  • Set your machine as you normally use it say, with two monitors using arandr or something. Then autorandr -s two-monitors
  • Set your machine in its alternate config, say, with the lid closed. Then autorandr -s closed-lid
  • Put autorandr -c in your ~.xprofile

This is enough for most things, ex­cept the bar sit­u­a­tion in QTile.

For that, I wrote two things. First a shell script that goes in ~/.config/autorandr/postswitch This is a "hook" that gets executed after the display configuration changes. Here's mine:

#!/bin/bash -x

notify-send "Switched to config $AUTORANDR_CURRENT_PROFILE"
killall -USR1 qtile  # Make qtile reread configuration

And why do I want qtile to reread its con­fig­u­ra­tion? Be­cause I want the systray to be on the "last" screen, which is al­ways larg­er :-)

Here's the relevant fragment from ~/.config/qtile/

screen_count = len(subprocess.check_output(shlex.split("xrandr --listmonitors")).splitlines()) -1

screens = [
            [ ... # List of widgets for this bar
            # Add systray in the LAST screen, otherwise invisible widget
            widget.Systray(padding=10) if i==screen_count-1 else widget.Sep(linewidth=0),),
    ) for i in range(screen_count)]  

This so­lu­tion re­quires a min­i­mum of set­up for my stan­dards (just con­fig­ure your screens once and a bit of code) and a max­i­mum of ben­e­fit:

  • The same con­fig works on all my ma­chi­nes, ex­cept for au­toran­dr pro­files, which have to be done on each com­put­er
  • It works in a to­tal­ly au­to­mat­ed man­ner, I nev­er need to move screens around
  • It will work on any fu­ture com­put­ers thank to chez­moi

Chrome hates WMs

The Problem

I have seen it a few times in the past. I change WMs or desk­tops and sud­den­ly chrome has no idea where my pass­words wen­t. They are there in pass­word­s.­google.­com but chrome nev­er aut­ofill­s, and they are not list­ed in my lo­cal pro­file.

The Solution

Make sure you are running gnome-keyring-daemon and add this in ~/.config/chrome-flags.conf


The Other Solution

You want a pass­word store that is not chrome. I have one in ad­di­tion of chrome, us­ing pass

This keeps my pass­words en­crypt­ed in Git (y­ou can use GitHub, I use my per­son­al gitea) and you can ac­cess them from the com­mand line, from a Chrome ex­ten­sion, or from a but­ton in my desk­top bar us­ing rofi-­pass

This en­sures I nev­er will lose ac­cess to my pass­word­s, and max­i­mizes the ways I can get to them while keep­ing things nice and se­cure.

Automounting Devices

The Problem

While I know per­fect­ly well how to mount de­vices in Lin­ux, I'd rather they mount them­selves.

The Solution

Use ud­iskie it's lightweight, nice­ly in­te­grat­ed, and it just works well by de­fault.


The Problem

I want desk­top no­ti­fi­ca­tion­s.

The solution

Use dun­st it's lightweight, nice­ly in­te­grat­ed, and it just works well by de­fault.

Screen Locking

The Problem

I want my screen to lock, but don't want any­thing fan­cy.

The Solution

Use xss-lock and slock

While slock in itself works great, xss-lock integrates it with loginctl so it works better. Just add this to your ~/.xprofile:

xss-lock slock &

Pretty Icons and Colors

The Problem

I want sim­ple icons that are not very col­or­ful, so they in­te­grate with what­ev­er col­or scheme I am us­ing.

The Solution

Since I am fol­low­ing more or less a nord col­or scheme I am us­ing a com­bi­na­tion of Nordzy icons and just us­ing font-awe­some

Here are some snip­pets from the qtile con­fig. Where I am point­ing icons to a spe­cif­ic fold­er, that fold­er con­tains copies of nordzy icons con­vert­ed to PNG with trans­par­ent back­ground­s:

    [ ...
        widget.GroupBox(highlight_method="block", foreground="2e3440", active="d08770", inactive="4c566a", this_current_screen_border="242831",this_screen_border="88c0d0"),
        widget.BatteryIcon(theme_path="/home/ralsina/.config/qtile/battery_icons", background="d8dee9", mouse_callbacks=power_callbacks),
        widget.Volume(fmt="",padding=0, theme_path="/home/ralsina/.config/qtile/battery_icons"),
        widget.LaunchBar(padding=0, text_only=True, font="Font Awesome 6 Free", fontsize=16, foreground="2e3440", progs=[
                    ("", "rofi-bluetooth", "Bluetooth"),
                    ("", "rofi -modi 'clipboard:greenclip print' -show", "Clipboard History"),
                    ("", "rofi-pass", "Passwords"),
                    ("", "rofi-todo -f /home/ralsina/todo.txt", "Todo"),
                    ("", "flameshot gui", "Screenshot"),
    border_width=[1, 0, 0, 0],  # Draw top and bottom borders
    border_color=["b48ead","b48ead","b48ead","b48ead" ],  # Borders are magenta

Then I configured styles and icons for gtk apps (using lxappearance) and Qt apps (using qt5ct) and things now look decent.

Color Schemes

The Problem

I want a co­or­di­nat­ed col­or scheme in the dis­parate tools I am us­ing.

The Solution

Up­date: I wrote a more tu­to­ri­al-­like thing about this called Col­or Co­or­di­na­tion Us­ing Base16

En­ter flavours, a tool to gen­er­ate con­fig­u­ra­tions for dif­fer­ent things out of sim­ple tem­plates and pre­de­fined col­or schemes.

It al­ready sup­port­ed my ter­mi­nal (alacrit­ty) and rofi, just need­ed to cre­ate tem­plates for my qtile con­fig:

colors = {
    "background": "#{{base00-hex}}",
    "background-lighter": "#{{base01-hex}}",
    "selection-background": "#{{base02-hex}}",
    "comments": "#{{base03-hex}}",
    "foreground-dark": "#{{base04-hex}}",
    "foreground": "#{{base05-hex}}",
    "foreground-light": "#{{base06-hex}}",
    "background-light": "#{{base07-hex}}",
    "variables": "#{{base08-hex}}",
    "integers": "#{{base09-hex}}",
    "bold": "#{{base0A-hex}}",
    "strings": "#{{base0B-hex}}",
    "quotes": "#{{base0C-hex}}",
    "headings": "#{{base0D-hex}}",
    "italic": "#{{base0E-hex}}",
    "tags": "#{{base0F-hex}}",

And my tmux­er (zel­li­j):

themes {
    default {
        fg "#{{base05-hex}}"
        bg "#{{base00-hex}}"
        black "#{{base00-hex}}"
        red "#{{base08-hex}}"
        green "#{{base0B-hex}}"
        yellow "#{{base0A-hex}}"
        blue "#{{base0D-hex}}"
        magenta "#{{base0E-hex}}"
        cyan "#{{base0C-hex}}"
        white "#{{base05-hex}}"
        orange "#{{base09-hex}}"

And put the right in­can­ta­tions in the flavours con­fig (par­tial):

file = "~/.config/qtile/"
template = "ralsina"
subtemplate = "qtile"
rewrite = true
hook = "killall -USR1 qtile"

file = "~/.config/zellij/themes/default.kdl"
template = "ralsina"
subtemplate = "zellij"
rewrite = true

I will have to configure everything I want to follow my colour scheme but I can apply it to everything with a simple command like flavours apply monokai

As an ex­tra, here's a script that lets you choose the col­or scheme us­ing rofi:


LAST_SCHEME=$(cat ~/.local/share/flavours/lastscheme)
SELECTED=$(flavours list | sed 's/\s/\n/g' | grep -n $LAST_SCHEME | cut -d: -f1)

flavours apply $(flavours list| sed 's/\s/\n/g' | rofi -dmenu -selected-row $SELECTED)

rofi choosing a color scheme


What can I say, I like it, it's not ug­ly, has all the func­tion­al­i­ty I want­ed and us­es around 400MB of RAM be­fore I start chrome. I am quite en­joy­ing it.

While this site (in­ten­tion­al­ly) has no com­ments, feel free to dis­cuss this in Red­dit

Contents © 2000-2024 Roberto Alsina