complete-computing-environment/i3wm-kde.org

332 lines
12 KiB
Org Mode

:PROPERTIES:
:ID: 20211206T133356.501203
:END:
#+title: i3wm with NixOS and KDE
#+FILETAGS: :Project:CCE:
Since I am de-programming myself from [[id:cce/exwm][EXWM]] right now, thinking of a [[id:20211116T135637.841698][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
:PROPERTIES:
:ID: 20211206T133651.674012
:ROAM_ALIASES: i3wm
:END:
* i3 on NixOS via home-manager
:PROPERTIES:
:ID: 20211206T133643.185810
:END:
[[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][NixOS]] users of course support i3wm. I like the [[id:cce/home-manager][home-manager]] module more though.
This is an [[id:arroyo/home-manager][Arroyo Home Manager]] module:
#+ARROYO_HOME_MODULE: hm/i3wm.nix
#+ARROYO_SYSTEM_ROLE: endpoint
#+begin_src nix :tangle ~/arroyo-nix/hm/i3wm.nix :noweb yes
{ 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>>
};
};
}
#+end_src
(of course I use [[id:cce/vulfpeck_fonts_are_fun][Vulfpeck Fonts!]])
** Command strings and variables
Some of these commands are defined in [[id:20211116T135637.841698][A World Without EXWM]].
#+name: extraConfig_table
| 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 |
#+name: extraConfig_variables
#+begin_src emacs-lisp :var tbl=extraConfig_table :results drawer :exports both
(s-join "\n" (--map (format "set $%s \"%s\"" (first it) (second it)) tbl))
#+end_src
** Making i3 work on with KDE Plasma
Within =extraConfig= the =no_focus= rule and the =for_window= rules are provided by [[https://userbase.kde.org/Tutorials/Using_Other_Window_Managers_with_Plasma][KDE's guides to using i3 and other window managers with Plasma]]. This is set up differently than my [[id:cce/exwm][EXWM]] configuration in that I'm instructing [[id:cce/kde_is_a_base_for_my_emacs_desktop][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.
#+name: extraConfig
#+begin_src text
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"]
#+end_src
** i3 Keybindings
:PROPERTIES:
:ID: 20220103T092342.496886
:ROAM_ALIASES: "i3wm Keybindings"
:END:
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 [[id:cce/keyboardio_atreus][Keyboardio Atreus]] layout.
#+NAME: keybindings_tbl
| 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:
#+name: keybindings_var
#+begin_src emacs-lisp :var tbl=keybindings_tbl :results drawer :exports both
(s-join "\n" (--map (format "\"${mod}+%s\" = \"%s\";"
(first it) (second it))
tbl))
#+end_src
And inserted here:
#+NAME: keybindings
#+begin_src nix :noweb yes
keybindings = {
<<keybindings_var()>>
};
#+end_src
** i3 Shortcut Mode for hopping in to Emacs
:PROPERTIES:
:ID: 20220113T193644.575645
:END:
When hitting =Super-;= my i3 goes in to a "shortcuts" mode for launching common [[id:cce/emacs][Emacs]] tasks. I use the =emacs-daemon= so that I always have an Emacs running in the background.
#+NAME: shortcutMode_tbl
| 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:
#+name: shortcutMode_var
#+begin_src emacs-lisp :var tbl=shortcutMode_tbl :results drawer :exports both
(s-join "\n" (--map (format "\"%s\" = \"%s; mode default\";"
(first it) (second it))
tbl))
#+end_src
And inserted here:
#+NAME: shortcutMode
#+begin_src nix :noweb yes
modes.emacs = {
<<shortcutMode_var()>>
"Escape" = "mode default";
};
#+end_src
Which is included at the top-level configuration.
** i3 Appearance and Colors
I don't use i3's bar -- i use [[id:cce/kde_is_a_base_for_my_emacs_desktop][KDE]] Plasma's panel. It's fine enough, and it means I don't have to fight to get a decent network manager dialog...
#+NAME: appearanceConfiguration
#+begin_src nix
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";
};
};
#+end_src
** INPROGRESS Window Assignment Rules
:LOGBOOK:
- State "INPROGRESS" from "NEXT" [2021-12-09 Thu 11:01]
:END:
- 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
#+NAME: windowAssigns
#+begin_src nix
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"; }];
};
#+end_src
** INPROGRESS startup commands
:LOGBOOK:
- State "INPROGRESS" from [2021-12-09 Thu 11:02]
:END:
Really would like this to check if an instance is already running but this is a decent way to start.
#+NAME: startupCommands
#+begin_src nix
startup = [
{ command = "${pkgs.syncthingtray}/bin/syncthingtray"; }
{ command = "element-desktop"; }
{ command = "signal-desktop"; }
{ command = "cantata"; }
{ command = "${pkgs.picom}/bin/picom"; }
# { command = "emacs"; }
];
#+end_src
* i3 on KDE
:PROPERTIES:
:ID: 20211206T133646.220023
:END:
:LOGBOOK:
- State "DONE" from "NEXT" [2021-12-14 Tue 16:46]
:END:
- list of global shortcuts i need to disable (maybe with =kwriteconfig= command runner...)
KDE makes it [[https://userbase.kde.org/Tutorials/Using_Other_Window_Managers_with_Plasma][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 [[id:20220421T100313.402598][Trying out XMonad in Home Manager]]
#+NAME: kdewm_variable
#+begin_src nix
home.sessionVariables = {
KDEWM="${pkgs.i3}/bin/i3";
};
#+end_src
* NEXT Evaluate Layout Tools
- i3-auto-layout https://github.com/chmln/i3-auto-layout
- i3-balance-workspace https://github.com/atreyasha/i3-balance-workspace
- i3-wk-switch https://github.com/tmfink/i3-wk-switch
- i3-ratiosplit https://github.com/333fred/i3-ratiosplit