complete-computing-environment/i3wm-kde.org

12 KiB
Raw Permalink Blame History

i3wm with NixOS and KDE

Since I am de-programming myself from EXWM right now, thinking of a A World Without EXWM, I have been thinking hard about whether I need a "tiling window manager" and the simple answer is yes I do.

NEXT why do I need a tiling window manager

NEXT an evaluation of window managers with an eye towards Wayland future

NEXT what does i3 bring

i3 on NixOS via home-manager

NixOS users of course support i3wm. I like the home-manager module more though.

This is an Arroyo Home Manager module:

{ config, pkgs, callPackage, ... }:

let
  mod = "Mod4";
in {
  # <<kdewm_variable>>
  xsession.windowManager.i3 = {
    enable = false;
    extraConfig = ''
    <<extraConfig_variables(extraConfig_table)>>
    <<extraConfig>>
    '';
    config = {
      modifier = mod;
      terminal = "${pkgs.konsole}/bin/konsole";
      fonts = {
        names = ["Vulf Mono"];
        style = "Regular Italic";
        size = 11.0;
      };
      workspaceAutoBackAndForth = true;
      # consider how to get ws5 to be on the laptop only when bedroom 4k is connected, luser
      # workspaceOutputAssign = {
      #   { output = "HDMI-1";
      #     workspace = "$ws1";
      #   };
      # };
      window.hideEdgeBorders = "smart";
      defaultWorkspace = "$ws1";
      focus.followMouse = true;
      <<startupCommands>>
      <<windowAssigns>>
      <<appearanceConfiguration>>
      <<keybindings>>
      <<shortcutMode>>
    };
  };
}

(of course I use Vulfpeck Fonts!)

Command strings and variables

Some of these commands are defined in A World Without EXWM.

name value
mod Mod4
ec emacsclient -c -n
mail emacsclient -c -e '(gnus)' -n
mpc emacsclient -c -e '(mpc)' -n
srs emacsclient -c -e '(srs)' -n
metax meta-x
journal org-journal
todos org-todos
agenda org-agenda
logout qdbus org.kde.ksmserver /KSMServer logout -1 2 3
ws1 1: hack
ws2 2: comm
ws3 3: muse
ws4 4: game
ws5 5: meet
(s-join "\n" (--map (format "set $%s \"%s\"" (first it) (second it)) tbl))

Making i3 work on with KDE Plasma

Within extraConfig the no_focus rule and the for_window rules are provided by KDE's guides to using i3 and other window managers with Plasma. This is set up differently than my EXWM configuration in that I'm instructing KDE to start the desktop with i3wm as the window manager rather than kwin. EXWM is kind enough to ask me if it can replace kwin, but with a native tiling WM I really just want the thing to run, I guess. These rules basically make the common KDE windows float and behave rationally.

for_window [title="Desktop — Plasma"] kill, floating enable, border none
for_window [class="plasmashell"] floating enable
for_window [class="Plasma"] floating enable, border none
for_window [title="plasma-desktop"] floating enable, border none
for_window [title="win7"] floating enable, border none
for_window [class="krunner"] floating enable, border none
for_window [class="Kmix"] floating enable, border none
for_window [class="Klipper"] floating enable, border none
for_window [class="Plasmoidviewer"] floating enable, border none
for_window [class="plasmashell" window_type="notification"] floating enable, border none, move right 700px, move down 450px
no_focus [class="plasmashell" window_type="notification"]

i3 Keybindings

I use a pretty simple set of keybindings, some of it is lifted from how I used EXWM, some of it is from the default i3 configuration, some of it comes from a quick tour of roam:Krohnkite, some of it is designed to compose around my Keyboardio Atreus layout.

key command
a layout tabbed
s layout stacking
d layout default
f fullscreen toggle global
Shift+q kill
1 workspace $ws1
2 workspace $ws2
3 workspace $ws3
4 workspace $ws4
5 workspace $ws5
Shift+1 move container to workspace $ws1
Shift+2 move container to workspace $ws2
Shift+3 move container to workspace $ws3
shift+4 move container to workspace $ws4
Shift+5 move container to workspace $ws5
Return exec $ec
Shift+Return exec ${pkgs.konsole}/bin/konsole
Shift+z exec $logout
x exec $metax
semicolon mode emacs
apostrophe exec $journal
i split toggle
h focus parent
j focus next
k focus prev
l focus child
Shift+h move left
Shift+j move down
Shift+k move up
Shift+l move right
Up focus up
Down focus down
Left focus left
Right focus right
bracketleft workspace prev
bracketright workspace next
Shift+bracketleft move container to workspace prev
Shift+bracketright move container to workspace next
Shift+9 move workspace to output prev
Shift+0 move workspace to output next

This table is processed in to configuration strings like:

(s-join "\n" (--map (format "\"${mod}+%s\" = \"%s\";"
                            (first it) (second it))
                    tbl))

And inserted here:

keybindings = {
  <<keybindings_var()>>
};

i3 Shortcut Mode for hopping in to Emacs

When hitting Super-; my i3 goes in to a "shortcuts" mode for launching common Emacs tasks. I use the emacs-daemon so that I always have an Emacs running in the background.

key command
x exec $meta-x
s exec $srs
c exec $journal
n exec $ec
m exec $mail
p exec $mpc
v exec $agenda
Shift+v exec $todos

This table is processed in to configuration strings like:

(s-join "\n" (--map (format "\"%s\" = \"%s; mode default\";"
                            (first it) (second it))
                    tbl))

And inserted here:

modes.emacs = {
  <<shortcutMode_var()>>

  "Escape" = "mode default";
};

Which is included at the top-level configuration.

i3 Appearance and Colors

I don't use i3's bar i use KDE Plasma's panel. It's fine enough, and it means I don't have to fight to get a decent network manager dialog…

bars = [];
colors = {
  focused = {
    background = "#4f7410"; border = "#4c7899";
    childBorder = "#1b2229"; indicator = "#2e9ef4";
    text = "#dfdfdf";
  };
  unfocused = {
    background = "#95836f"; border = "#4c7899";
    childBorder = "#23272e"; indicator = "#2e9ef4";
    text = "#dfdfdf";
  };
  urgent = {
    background = "#ff4e00"; border = "#4c7899";
    childBorder = "#ff7000"; indicator = "#2e9ef4";
    text = "#dfdfdf";
  };
};

INPROGRESS Window Assignment Rules

  • State "INPROGRESS" from "NEXT" [2021-12-09 Thu 11:01]
  • would be nice to move my firefoxen to different workspaces based on their title etc (move meet on to secondary display)
  • chat + music on a seconary workspace
assigns = {
  "$ws1" = [];
  "$ws2" = [{ class = "^Element$"; }
            { class = "^Signal$"; }
            { class = "^discord$"; }];
  "$ws3" = [{ class = "cantata"; }];
  "$ws4" = [{ class = "^Steam$"; }
            { class = "^cogmind$"; }];
  "$ws5" = [{ title = "^Meet.*"; }
            { class = "^zoom$"; }];
};
floating = {
  criteria = [{ title = "Steam - Update News"; }
              { title = "Steam - News (1 of 2)"; }
              { title = "Steam - News"; }
              { class = "spectacle"; }];
};

INPROGRESS startup commands

  • State "INPROGRESS" from [2021-12-09 Thu 11:02]

Really would like this to check if an instance is already running but this is a decent way to start.

startup = [
  { command = "${pkgs.syncthingtray}/bin/syncthingtray"; }
  { command = "element-desktop"; }
  { command = "signal-desktop"; }
  { command = "cantata"; }
  { command = "${pkgs.picom}/bin/picom"; }
  # { command = "emacs"; }
];

i3 on KDE

  • State "DONE" from "NEXT" [2021-12-14 Tue 16:46]
  • list of global shortcuts i need to disable (maybe with kwriteconfig command runner…)

KDE makes it easy enough to override the window manager in X11 land still. Easier than any of the other "desktop environments" I tried on Linux, at least. It's why I still use it.

This is disabled while I am Trying out XMonad in Home Manager

home.sessionVariables = {
  KDEWM="${pkgs.i3}/bin/i3";
};