summary refs log tree commit diff
path: root/nixos.org
blob: 4d901a7d50baaf5bce4f2e7edad54baaf83faad6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
#+TITLE:Nixos Config
#+AUTHOR: Crazazy
#+INCLUDE: ./style.org
For now this is the way I'm configuring nixos. There is no flakes here, just a configuration.nix and a bunch of other
stuff
* Prefix
  The nixos config is going to consist of a bunch of "imports" which are just a bunch of configs
  in the imports part of the main configuration. Then we can put each part of said config on its own source block
  This does require a bit of a prefix, that lets us access packages, existing configuration and library functions
  #+begin_src nix :tangle configuration.nix :noweb no-export :padline no
    { config, lib, pkgs, ... }:
    let
      sources = import ./nix/sources.nix;
      nur = import sources.NUR { inherit pkgs; };
      nurModules = import sources.NUR { };
    in
    {
      imports = [
        <<nixos-config>>
      ];
    }
  #+end_src
* Configuration
  :PROPERTIES:
  :header-args: :tangle no :noweb-ref nixos-config
  :END:

** Hardware
   Normal nixos installation comes with a hardware-configuration file. we are not going to add the contents of that
   file here ourself, but instead add it as an external module. This is the only place where we'll do this
   #+begin_src nix
     ./hardware-configuration.nix
   #+end_src
   Also i want to have a full bluetooth experience
   #+begin_src nix
     {
       hardware.bluetooth = {
         enable = true;
         package = pkgs.bluez;
       };
     }
   #+end_src
** personal stuff
   First, some personal stuff, so that I can tel people my computer is mine
   #+begin_src nix
     {
       options.mainUser = with lib; mkOption {
         type = types.str;
         default = builtins.getEnv "USER";
       };
     }
   #+end_src

   and then the actual info:
   #+begin_src nix
     {
       mainUser = "erik";
       networking.hostName = "RACEMONSTER";
       time.timeZone = "Europe/Amsterdam";
     }
   #+end_src
** Main user config
   This sets up a (secret) default password for the main user and also sets some default groups
   #+begin_src nix
     {
       users.mutableUsers = false;
       # Define a user account. Don't forget to set a password with ‘passwd’.
       users.users.${config.mainUser} = {
         initialHashedPassword = "$6$XTH/sALyqg$G.bMWemErh4KGCAjUfT16DL96QMn/4NTmxlw6Z26wUVJn.tagQG.Fzmrz7uPkdiWZbBBFWP36.YA4hw9AcL8Q1";
         isNormalUser = true;
         extraGroups = [ "video" "wheel" "NetworkManager" ]; # Enable ‘sudo’ for the user.
         # shell = pkgs.nushell;
       };
     }
   #+end_src
   Furthermore, I want to have some prefabs available in my $PATH if I make them
   #+begin_src nix
     {
       environment.shellInit =
         ''
          if [ -h /etc/nixos/nix-prefabs/result ]; then
           export PATH=$PATH:/etc/nixos/nix-prefabs/result/bin
          fi
         '';
     }
   #+end_src
** Init system
   nixos is started with systemd-boot, since we don't run any other distros
   #+begin_src nix
     {
       boot.loader.systemd-boot.enable = true;
       boot.loader.efi.canTouchEfiVariables = true;
     }
   #+end_src
** nixpkgs setup
   not much info here right now. emacs itself now refers to emacsng
   #+begin_src nix
     {
       nix.package = pkgs.nixVersions.stable;
       programs.nix-ld = {
         enable = true;
         # use all the libraries that AppImage uses to load an image
         libraries = with pkgs; [fuse] ++ (with appimageTools.defaultFhsEnvArgs; multiPkgs pkgs ++ targetPkgs pkgs);
       };
       nixpkgs.config.allowUnfree = true;
       nixpkgs.overlays = [
         (final: prev: {
           emacs = (import sources.emacs-ng).outputs.packages."x86_64-linux".default;
           emacsWithPackages = final.emacs.pkgs.withPackages;
         })
       ];
     }
   #+end_src
*** cachix
    Cachix and other substitute servers allow you to not have to compile things as much as you are supposed to
    We will create a small module for cachix before we put in the rest declaratively
    #+begin_src nix
      {
        options.nix.cacheAttrs = with lib; mkOption {
          type = with types; attrsOf str;
          default = {};

        };
        config = with lib; {
          nix.settings.substituters = builtins.attrNames config.nix.cacheAttrs;
          nix.settings.trusted-public-keys = builtins.attrValues config.nix.cacheAttrs;
        };
      }
    #+end_src
    With the config in hand, we can now quickly and easily declare our substitute servers
    #+begin_src nix
      {
        nix.cacheAttrs = {
          "https://crazazy.cachix.org" = "crazazy.cachix.org-1:3KaIHK26pkvd5palJH5A4Re1Hn2+GDV+aXYnftMYAm4=";
          "https://emacsng.cachix.org" = "emacsng.cachix.org-1:i7wOr4YpdRpWWtShI8bT6V7lOTnPeI7Ho6HaZegFWMI=";
          # "https://ethancedwards8.cachix.org" = "ethancedwards8.cachix.org-1:YMasjqyFnDreRQ9GXmnPIshT3tYyFHE2lUiNhbyIxOc=";
          "https://nix-community.cachix.org" = "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
          # "https://nrdxp.cachix.org" = "nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4=";
          # "https://rycee.cachix.org" = "rycee.cachix.org-1:TiiXyeSk0iRlzlys4c7HiXLkP3idRf20oQ/roEUAh/A=";
          # "https://cache.iog.io" = "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=";
        };
      }
    #+end_src
** udev binds
   I have a bindmount system so that I can easily make binds to persistent directories from my home directory
   This should prevent clutter
*** The config
    This part is quite advanced. It makes entries for filesystems and then makes a systemd service to re-assign
    generated temporary directories to the owner of the home folder
    #+begin_src nix
      {
        options = with lib; {
          homeBinds = mkOption {
            type = with types; listOf str;
            default = [ ];
            description = "Bind mounts in your home folder";
          };
          persistRoot = mkOption {
            type = types.str;
            default = "/nix/persist";
          };
        };
        config = with lib; mkIf (config.homeBinds != [ ]) {
          fileSystems = genAttrs (map (loc: "/home/${config.mainUser}/${loc}") config.homeBinds)
            (loc: {
              device = "${config.persistRoot}${loc}";
              fsType = "none";
              options = [ "bind" ];
            });
          systemd.services.fix-home-perms = {
            wantedBy = [ "multi-user.target" ];
            after = map (loc: "${builtins.replaceStrings ["/"] ["-"] loc}.mount") config.homeBinds;
            serviceConfig.Type = "oneshot";
            script = "chown -R ${config.mainUser} /home/${config.mainUser}";
          };
        };
      }
    #+end_src
*** The binds
    These are the binds themselves, they change frequently
    #+begin_src nix
      {
        homeBinds = [
          ".config/keybase"
          ".local/share/keybase"
          ".ssh"
          "Desktop"
          "Documents/uni-docs"
          "Documents/IdeaProjects"
          "Documents/java-jars"
          "Documents/notes"
          "Music"
          "Videos"
        ];
      }
    #+end_src
** Visual stuff
   I don't acutally literally live in the terminal. So we have to implement some xorg and other stuff
*** Basics
    Enable printing, sound and a good keyboard, along with x11 itself
    #+begin_src nix
      {
        # Enable CUPS to print documents.
        services.printing.enable = true;

        # Enable sound.
        sound.enable = true;
        hardware.pulseaudio.enable = true;

        # Enable the X11 windowing system.
        services.xserver.enable = true;
        services.xserver.layout = "us";
        services.xserver.xkbVariant = "altgr-intl";
        services.xserver.xkbOptions = "eurosign:e";
        # touchpad controls
        services.xserver.libinput.enable = true;
      }
    #+end_src
*** openbox
    I've decided to embrace minimal-ness and make an openbox config
    #+begin_src nix
      {
        services.xserver.displayManager.lightdm.enable = true;
        services.xserver.windowManager.openbox.enable = true;
        environment.systemPackages = with pkgs; [
          obconf openbox-menu rox-filer brightnessctl
        ];
        environment.etc."xdg/openbox/autostart.sh" = {
          mode = "0700";
          text = ''
            ${pkgs.tint2}/bin/tint2
          '';
        };
        environment.etc."xdg/openbox/menu.xml".text = ''
          <openbox_menu>
            <menu
              id="root-menu"
              label="OpenBox 3"
              execute="${pkgs.menumaker}/bin/mmaker -ci openbox -t xterm | sed -e 's/menu/openbox_pipe_menu/g'"
             />
             <item label="Browser" execute="vimb"/>
             <item label="Editor" execute="emacseditor -c"/>
           </openbox_menu>
        '';
        environment.etc."xdg/openbox/rc.xml".source = ./rc.xml;
      }
    #+end_src
    For keybinds, we also need an =rc.xml= file
    #+begin_src xml :tangle rc.xml :noweb-ref no
      <?xml version="1.0" encoding="UTF-8"?>

      <!-- Do not edit this file, it will be overwritten on install.
      Copy the file to $HOME/.config/openbox/ instead. -->

      <openbox_config xmlns="http://openbox.org/3.4/rc"
                      xmlns:xi="http://www.w3.org/2001/XInclude">

        <resistance>
          <strength>10</strength>
          <screen_edge_strength>20</screen_edge_strength>
        </resistance>

        <focus>
          <focusNew>yes</focusNew>
          <!-- always try to focus new windows when they appear. other rules do
               apply -->
          <followMouse>no</followMouse>
          <!-- move focus to a window when you move the mouse into it -->
          <focusLast>yes</focusLast>
          <!-- focus the last used window when changing desktops, instead of the one
               under the mouse pointer. when followMouse is enabled -->
          <underMouse>no</underMouse>
          <!-- move focus under the mouse, even when the mouse is not moving -->
          <focusDelay>200</focusDelay>
          <!-- when followMouse is enabled, the mouse must be inside the window for
               this many milliseconds (1000 = 1 sec) before moving focus to it -->
          <raiseOnFocus>no</raiseOnFocus>
          <!-- when followMouse is enabled, and a window is given focus by moving the
               mouse into it, also raise the window -->
        </focus>

        <placement>
          <policy>Smart</policy>
          <!-- 'Smart' or 'UnderMouse' -->
          <center>yes</center>
          <!-- whether to place windows in the center of the free area found or
               the top left corner -->
          <monitor>Primary</monitor>
          <!-- with Smart placement on a multi-monitor system, try to place new windows
               on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
               the active window is, 'Primary' - only on the primary monitor -->
          <primaryMonitor>1</primaryMonitor>
          <!-- The monitor where Openbox should place popup dialogs such as the
               focus cycling popup, or the desktop switch popup.  It can be an index
               from 1, specifying a particular monitor.  Or it can be one of the
               following: 'Mouse' - where the mouse is, or
               'Active' - where the active window is -->
        </placement>

        <theme>
          <name>Clearlooks</name>
          <titleLayout>NLIMC</titleLayout>
          <!--
              available characters are NDSLIMC, each can occur at most once.
              N: window icon
              L: window label (AKA title).
              I: iconify
              M: maximize
              C: close
              S: shade (roll up/down)
              D: omnipresent (on all desktops).
          -->
          <keepBorder>yes</keepBorder>
          <animateIconify>yes</animateIconify>
          <font place="ActiveWindow">
            <name>sans</name>
            <size>8</size>
            <!-- font size in points -->
            <weight>bold</weight>
            <!-- 'bold' or 'normal' -->
            <slant>normal</slant>
            <!-- 'italic' or 'normal' -->
          </font>
          <font place="InactiveWindow">
            <name>sans</name>
            <size>8</size>
            <!-- font size in points -->
            <weight>bold</weight>
            <!-- 'bold' or 'normal' -->
            <slant>normal</slant>
            <!-- 'italic' or 'normal' -->
          </font>
          <font place="MenuHeader">
            <name>sans</name>
            <size>9</size>
            <!-- font size in points -->
            <weight>normal</weight>
            <!-- 'bold' or 'normal' -->
            <slant>normal</slant>
            <!-- 'italic' or 'normal' -->
          </font>
          <font place="MenuItem">
            <name>sans</name>
            <size>9</size>
            <!-- font size in points -->
            <weight>normal</weight>
            <!-- 'bold' or 'normal' -->
            <slant>normal</slant>
            <!-- 'italic' or 'normal' -->
          </font>
          <font place="ActiveOnScreenDisplay">
            <name>sans</name>
            <size>9</size>
            <!-- font size in points -->
            <weight>bold</weight>
            <!-- 'bold' or 'normal' -->
            <slant>normal</slant>
            <!-- 'italic' or 'normal' -->
          </font>
          <font place="InactiveOnScreenDisplay">
            <name>sans</name>
            <size>9</size>
            <!-- font size in points -->
            <weight>bold</weight>
            <!-- 'bold' or 'normal' -->
            <slant>normal</slant>
            <!-- 'italic' or 'normal' -->
          </font>
        </theme>

        <desktops>
          <!-- this stuff is only used at startup, pagers allow you to change them
               during a session

      these are default values to use when other ones are not already set
      by other applications, or saved in your session

      use obconf if you want to change these without having to log out
      and back in -->
          <number>4</number>
          <firstdesk>1</firstdesk>
          <names>
            <!-- set names up here if you want to, like this:
                 <name>desktop 1</name>
                 <name>desktop 2</name>
            -->
          </names>
          <popupTime>875</popupTime>
          <!-- The number of milliseconds to show the popup for when switching
               desktops.  Set this to 0 to disable the popup. -->
        </desktops>

        <resize>
          <drawContents>yes</drawContents>
          <popupShow>Nonpixel</popupShow>
          <!-- 'Always', 'Never', or 'Nonpixel' (xterms and such) -->
          <popupPosition>Center</popupPosition>
          <!-- 'Center', 'Top', or 'Fixed' -->
          <popupFixedPosition>
            <!-- these are used if popupPosition is set to 'Fixed' -->

            <x>10</x>
            <!-- positive number for distance from left edge, negative number for
                 distance from right edge, or 'Center' -->
            <y>10</y>
            <!-- positive number for distance from top edge, negative number for
                 distance from bottom edge, or 'Center' -->
          </popupFixedPosition>
        </resize>

        <!-- You can reserve a portion of your screen where windows will not cover when
             they are maximized, or when they are initially placed.
             Many programs reserve space automatically, but you can use this in other
             cases. -->
        <margins>
          <top>0</top>
          <bottom>0</bottom>
          <left>0</left>
          <right>0</right>
        </margins>

        <dock>
          <position>TopLeft</position>
          <!-- (Top|Bottom)(Left|Right|)|Top|Bottom|Left|Right|Floating -->
          <floatingX>0</floatingX>
          <floatingY>0</floatingY>
          <noStrut>no</noStrut>
          <stacking>Above</stacking>
          <!-- 'Above', 'Normal', or 'Below' -->
          <direction>Vertical</direction>
          <!-- 'Vertical' or 'Horizontal' -->
          <autoHide>no</autoHide>
          <hideDelay>300</hideDelay>
          <!-- in milliseconds (1000 = 1 second) -->
          <showDelay>300</showDelay>
          <!-- in milliseconds (1000 = 1 second) -->
          <moveButton>Middle</moveButton>
          <!-- 'Left', 'Middle', 'Right' -->
        </dock>

        <keyboard>
          <chainQuitKey>C-g</chainQuitKey>

          <!-- Keybindings for desktop switching -->
          <keybind key="C-A-Left">
            <action name="GoToDesktop"><to>left</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="C-A-Right">
            <action name="GoToDesktop"><to>right</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="C-A-Up">
            <action name="GoToDesktop"><to>up</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="C-A-Down">
            <action name="GoToDesktop"><to>down</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="S-A-Left">
            <action name="SendToDesktop"><to>left</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="S-A-Right">
            <action name="SendToDesktop"><to>right</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="S-A-Up">
            <action name="SendToDesktop"><to>up</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="S-A-Down">
            <action name="SendToDesktop"><to>down</to><wrap>no</wrap></action>
          </keybind>
          <keybind key="W-F1">
            <action name="GoToDesktop"><to>1</to></action>
          </keybind>
          <keybind key="W-F2">
            <action name="GoToDesktop"><to>2</to></action>
          </keybind>
          <keybind key="W-F3">
            <action name="GoToDesktop"><to>3</to></action>
          </keybind>
          <keybind key="W-F4">
            <action name="GoToDesktop"><to>4</to></action>
          </keybind>
          <keybind key="W-d">
            <action name="ToggleShowDesktop"/>
          </keybind>

          <!-- Keybindings for windows -->
          <keybind key="A-F4">
            <action name="Close"/>
          </keybind>
          <keybind key="A-Escape">
            <action name="Lower"/>
            <action name="FocusToBottom"/>
            <action name="Unfocus"/>
          </keybind>
          <keybind key="A-space">
            <action name="ShowMenu"><menu>client-menu</menu></action>
          </keybind>

          <!-- Keybindings for window switching -->
          <keybind key="A-Tab">
            <action name="NextWindow">
              <finalactions>
                <action name="Focus"/>
                <action name="Raise"/>
                <action name="Unshade"/>
              </finalactions>
            </action>
          </keybind>
          <keybind key="A-S-Tab">
            <action name="PreviousWindow">
              <finalactions>
                <action name="Focus"/>
                <action name="Raise"/>
                <action name="Unshade"/>
              </finalactions>
            </action>
          </keybind>
          <keybind key="C-A-Tab">
            <action name="NextWindow">
              <panels>yes</panels><desktop>yes</desktop>
              <finalactions>
                <action name="Focus"/>
                <action name="Raise"/>
                <action name="Unshade"/>
              </finalactions>
            </action>
          </keybind>

          <!-- Keybindings for window switching with the arrow keys -->
          <keybind key="W-S-Right">
            <action name="DirectionalCycleWindows">
              <direction>right</direction>
            </action>
          </keybind>
          <keybind key="W-S-Left">
            <action name="DirectionalCycleWindows">
              <direction>left</direction>
            </action>
          </keybind>
          <keybind key="W-S-Up">
            <action name="DirectionalCycleWindows">
              <direction>up</direction>
            </action>
          </keybind>
          <keybind key="W-S-Down">
            <action name="DirectionalCycleWindows">
              <direction>down</direction>
            </action>
          </keybind>
          <keybind key="XF86MonBrightnessUp">
            <action name="Execute">
              <command>brightnessctl set +10%</command>
            </action>
          </keybind>
          <keybind key="XF86MonBrightnessDown">
            <action name="Execute">
              <command>brightnessctl set -10%</command>
            </action>
          </keybind>
          <keybind key="XF86AudioLowerVolume">
            <action name="Execute">
              <command>amixer set Master 10%-</command>
            </action>
          </keybind>
          <keybind key="XF86AudioRaiseVolume">
            <action name="Execute">
              <command>amixer set Master 10%+</command>
            </action>
          </keybind>

          <!-- Keybindings for running applications -->
          <keybind key="W-e">
            <action name="Execute">
              <startupnotify>
                <enabled>true</enabled>
                <name>Browser</name>
              </startupnotify>
              <command>rox</command>
            </action>
          </keybind>
        </keyboard>

        <mouse>
          <dragThreshold>1</dragThreshold>
          <!-- number of pixels the mouse must move before a drag begins -->
          <doubleClickTime>500</doubleClickTime>
          <!-- in milliseconds (1000 = 1 second) -->
          <screenEdgeWarpTime>400</screenEdgeWarpTime>
          <!-- Time before changing desktops when the pointer touches the edge of the
               screen while moving a window, in milliseconds (1000 = 1 second).
               Set this to 0 to disable warping -->
          <screenEdgeWarpMouse>false</screenEdgeWarpMouse>
          <!-- Set this to TRUE to move the mouse pointer across the desktop when
               switching due to hitting the edge of the screen -->

          <context name="Frame">
            <mousebind button="A-Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
            <mousebind button="A-Left" action="Click">
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="A-Left" action="Drag">
              <action name="Move"/>
            </mousebind>

            <mousebind button="A-Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="A-Right" action="Drag">
              <action name="Resize"/>
            </mousebind>

            <mousebind button="A-Middle" action="Press">
              <action name="Lower"/>
              <action name="FocusToBottom"/>
              <action name="Unfocus"/>
            </mousebind>

            <mousebind button="A-Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="A-Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>
            <mousebind button="C-A-Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="C-A-Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>
            <mousebind button="A-S-Up" action="Click">
              <action name="SendToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="A-S-Down" action="Click">
              <action name="SendToDesktop"><to>next</to></action>
            </mousebind>
          </context>

          <context name="Titlebar">
            <mousebind button="Left" action="Drag">
              <action name="Move"/>
            </mousebind>
            <mousebind button="Left" action="DoubleClick">
              <action name="ToggleMaximize"/>
            </mousebind>

            <mousebind button="Up" action="Click">
              <action name="if">
                <shaded>no</shaded>
                <then>
                  <action name="Shade"/>
                  <action name="FocusToBottom"/>
                  <action name="Unfocus"/>
                  <action name="Lower"/>
                </then>
              </action>
            </mousebind>
            <mousebind button="Down" action="Click">
              <action name="if">
                <shaded>yes</shaded>
                <then>
                  <action name="Unshade"/>
                  <action name="Raise"/>
                </then>
              </action>
            </mousebind>
          </context>

          <context name="Titlebar Top Right Bottom Left TLCorner TRCorner BRCorner BLCorner">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>

            <mousebind button="Middle" action="Press">
              <action name="Lower"/>
              <action name="FocusToBottom"/>
              <action name="Unfocus"/>
            </mousebind>

            <mousebind button="Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="ShowMenu"><menu>client-menu</menu></action>
            </mousebind>
          </context>

          <context name="Top">
            <mousebind button="Left" action="Drag">
              <action name="Resize"><edge>top</edge></action>
            </mousebind>
          </context>

          <context name="Left">
            <mousebind button="Left" action="Drag">
              <action name="Resize"><edge>left</edge></action>
            </mousebind>
          </context>

          <context name="Right">
            <mousebind button="Left" action="Drag">
              <action name="Resize"><edge>right</edge></action>
            </mousebind>
          </context>

          <context name="Bottom">
            <mousebind button="Left" action="Drag">
              <action name="Resize"><edge>bottom</edge></action>
            </mousebind>

            <mousebind button="Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="ShowMenu"><menu>client-menu</menu></action>
            </mousebind>
          </context>

          <context name="TRCorner BRCorner TLCorner BLCorner">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="Left" action="Drag">
              <action name="Resize"/>
            </mousebind>
          </context>

          <context name="Client">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
            <mousebind button="Middle" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
            <mousebind button="Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
          </context>

          <context name="Icon">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
              <action name="ShowMenu"><menu>client-menu</menu></action>
            </mousebind>
            <mousebind button="Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="ShowMenu"><menu>client-menu</menu></action>
            </mousebind>
          </context>

          <context name="AllDesktops">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="Left" action="Click">
              <action name="ToggleOmnipresent"/>
            </mousebind>
          </context>

          <context name="Shade">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
            <mousebind button="Left" action="Click">
              <action name="ToggleShade"/>
            </mousebind>
          </context>

          <context name="Iconify">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
            <mousebind button="Left" action="Click">
              <action name="Iconify"/>
            </mousebind>
          </context>

          <context name="Maximize">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="Middle" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="Left" action="Click">
              <action name="ToggleMaximize"/>
            </mousebind>
            <mousebind button="Middle" action="Click">
              <action name="ToggleMaximize"><direction>vertical</direction></action>
            </mousebind>
            <mousebind button="Right" action="Click">
              <action name="ToggleMaximize"><direction>horizontal</direction></action>
            </mousebind>
          </context>

          <context name="Close">
            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
              <action name="Unshade"/>
            </mousebind>
            <mousebind button="Left" action="Click">
              <action name="Close"/>
            </mousebind>
          </context>

          <context name="Desktop">
            <mousebind button="Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>

            <mousebind button="A-Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="A-Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>
            <mousebind button="C-A-Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="C-A-Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>

            <mousebind button="Left" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
            <mousebind button="Right" action="Press">
              <action name="Focus"/>
              <action name="Raise"/>
            </mousebind>
          </context>

          <context name="Root">
            <!-- Menus -->
            <mousebind button="Middle" action="Press">
              <action name="ShowMenu"><menu>client-list-combined-menu</menu></action>
            </mousebind>
            <mousebind button="Right" action="Press">
              <action name="ShowMenu"><menu>root-menu</menu></action>
            </mousebind>
          </context>

          <context name="MoveResize">
            <mousebind button="Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>
            <mousebind button="A-Up" action="Click">
              <action name="GoToDesktop"><to>previous</to></action>
            </mousebind>
            <mousebind button="A-Down" action="Click">
              <action name="GoToDesktop"><to>next</to></action>
            </mousebind>
          </context>
        </mouse>

        <menu>
          <!-- You can specify more than one menu file in here and they are all loaded,
               just don't make menu ids clash or, well, it'll be kind of pointless -->

          <!-- default menu file (or custom one in $HOME/.config/openbox/) -->
          <file>menu.xml</file>
          <hideDelay>200</hideDelay>
          <!-- if a press-release lasts longer than this setting (in milliseconds), the
               menu is hidden again -->
          <middle>no</middle>
          <!-- center submenus vertically about the parent entry -->
          <submenuShowDelay>100</submenuShowDelay>
          <!-- time to delay before showing a submenu after hovering over the parent
               entry.
               if this is a negative value, then the delay is infinite and the
               submenu will not be shown until it is clicked on -->
          <submenuHideDelay>400</submenuHideDelay>
          <!-- time to delay before hiding a submenu when selecting another
               entry in parent menu
               if this is a negative value, then the delay is infinite and the
               submenu will not be hidden until a different submenu is opened -->
          <showIcons>yes</showIcons>
          <!-- controls if icons appear in the client-list-(combined-)menu -->
          <manageDesktops>yes</manageDesktops>
          <!-- show the manage desktops section in the client-list-(combined-)menu -->
        </menu>

        <applications>
          <!--
              # this is an example with comments through out. use these to make your
              # own rules, but without the comments of course.
              # you may use one or more of the name/class/role/title/type rules to specify
              # windows to match

      <application name="the window's _OB_APP_NAME property (see obxprop)"
      class="the window's _OB_APP_CLASS property (see obxprop)"
      groupname="the window's _OB_APP_GROUP_NAME property (see obxprop)"
      groupclass="the window's _OB_APP_GROUP_CLASS property (see obxprop)"
      role="the window's _OB_APP_ROLE property (see obxprop)"
      title="the window's _OB_APP_TITLE property (see obxprop)"
      type="the window's _OB_APP_TYPE property (see obxprob)..
      (if unspecified, then it is 'dialog' for child windows)">
      # you may set only one of name/class/role/title/type, or you may use more
      # than one together to restrict your matches.

      # the name, class, role, and title use simple wildcard matching such as those
      # used by a shell. you can use * to match any characters and ? to match
      # any single character.

      # the type is one of: normal, dialog, splash, utility, menu, toolbar, dock,
      #    or desktop

      # when multiple rules match a window, they will all be applied, in the
      # order that they appear in this list


      # each rule element can be left out or set to 'default' to specify to not
      # change that attribute of the window

      <decor>yes</decor>
      # enable or disable window decorations

      <shade>no</shade>
      # make the window shaded when it appears, or not

      <position force="no">
      # the position is only used if both an x and y coordinate are provided
      # (and not set to 'default')
      # when force is "yes", then the window will be placed here even if it
      # says you want it placed elsewhere.  this is to override buggy
      # applications who refuse to behave
      <x>center</x>
      # a number like 50, or 'center' to center on screen. use a negative number
      # to start from the right (or bottom for <y>), ie -50 is 50 pixels from
      # the right edge (or bottom). use 'default' to specify using value
      # provided by the application, or chosen by openbox, instead.
      <y>200</y>
      <monitor>1</monitor>
      # specifies the monitor in a xinerama setup.
      # 1 is the first head, or 'mouse' for wherever the mouse is
      </position>

      <size>
      # the size to make the window.
      <width>20</width>
      # a number like 20, or 'default' to use the size given by the application.
      # you can use fractions such as 1/2 or percentages such as 75% in which
      # case the value is relative to the size of the monitor that the window
      # appears on.
      <height>30%</height>
      </size>

      <focus>yes</focus>
      # if the window should try be given focus when it appears. if this is set
      # to yes it doesn't guarantee the window will be given focus. some
      # restrictions may apply, but Openbox will try to

      <desktop>1</desktop>
      # 1 is the first desktop, 'all' for all desktops

      <layer>normal</layer>
      # 'above', 'normal', or 'below'

      <iconic>no</iconic>
      # make the window iconified when it appears, or not

      <skip_pager>no</skip_pager>
      # asks to not be shown in pagers

      <skip_taskbar>no</skip_taskbar>
      # asks to not be shown in taskbars. window cycling actions will also
      # skip past such windows

      <fullscreen>yes</fullscreen>
      # make the window in fullscreen mode when it appears

      <maximized>true</maximized>
      # 'Horizontal', 'Vertical' or boolean (yes/no)
      </application>

      # end of the example
          -->
        </applications>

      </openbox_config>

    #+end_src
** Networking
   Some default network settings for my laptop
   #+begin_src nix
     {
       networking.networkmanager.enable = true; # Enables wireless support via NetworkManager
     }
   #+end_src
** packages
*** Core packages
    These are the normal packages that I use for core maintenance. I use a special hardened version of firefox that takes in some addons as well
    [[https://github.com/nix-community/nur-combined/blob/master/repos/ijohanne/pkgs/firefox-hardened/default.nix][Hardened firefox source]]
    #+begin_src nix
      {
        environment.systemPackages = let
          myFirefox = with pkgs; wrapFirefox firefox-esr-unwrapped {
            nixExtensions = builtins.filter lib.isDerivation (builtins.attrValues nur.repos.crazazy.firefox-addons);

            extraPolicies = {
              CaptivePortal = false;
              DisableFirefoxStudies = true;
              DisablePocket = true;
              DisableTelemetry = true;
              DisableFirefoxAccounts = true;
              DontCheckDefaultBrowser = true;
              FirefoxHome = {
                Pocket = false;
                Snippets = false;
              };
              UserMessaging = {
                ExtensionRecommendations = false;
                SkipOnboarding = true;
              };
            };
            extraPrefs = ''
            // Show more ssl cert infos
            lockPref("security.identityblock.show_extended_validation", true);
            // Enable userchrome css
            lockPref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
            // Enable light dev tools
            lockPref("devtools.theme","light");
            // Misc other settings
            lockPref("extensions.autoDisableScopes", 0);
            lockPref("browser.uidensity", 1);
            lockPref("browser.search.openintab", true);
            lockPref("extensions.update.enabled", false);
            lockPref("identity.fxaccounts.enabled", false);
            lockPref("signon.rememberSignons", false);
            lockPref("signon.rememberSignons.visibilityToggle", false);
            lockPref("media.eme.enabled", true);
            lockPref("browser.eme.ui.enabled", true);
            lockPref("xpinstall.signatures.required",false);
            lockPref("browser.shell.checkDefaultBrowser", false );
          '';
          };
        in
          with pkgs; [
            bun
            # compcert
            curl
            # deno
            discord
            gitFull
            graalvm-ce
            libreoffice
            krdc
            mpv
            # nur.repos.crazazy.seamonkey
            # myFirefox
            vimb
            unzip zip
            vim
            (wine.override { wineBuild = "wineWow"; })
          ];
        # persistent directory for my browser details
        homeBinds = [
          # ".mozilla/firefox"
          ".config/discord"
          ".wine"
        ];
      }
    #+end_src
*** Researchware
    I am doing a research project and I need certain software to make that happen
    #+begin_src nix :noweb-ref no
      {
        virtualisation.vswitch.enable = true;
        environment.systemPackages = with pkgs; [
          mininet
          # not universal for all pythons but it works for now
          (python3.withPackages (p: [(p.mininet-python.overrideAttrs (_: {
            postInstall = "cp $py/bin/mn $py/lib/python3.10/site-packages/mininet/__main__.py";
          }))]))
          opam
          bindfs
        ];
      }
    #+end_src
*** Steam
    I like to play videogames sometimes, however steam also requires a little more special attention
    #+begin_src nix
      {
        imports = [
          # nurModules.repos.crazazy.modules.private.steam-config
        ];
        programs.steam.enable = true;
        homeBinds = [
          ".local/share/Steam"
        ];
        environment.systemPackages = with pkgs; [
          steam
        ];
      }
    #+end_src
*** Emacs
    Emacs needs to be integrated into the rest of the system. We are going to do that via a emacs daemon
    #+begin_src nix
      {
        services.emacs = {
          package = pkgs.emacs29;
          defaultEditor = true;
          enable = true;
        };
        homeBinds = [
          ".config/emacs"
        ];
      }
    #+end_src
*** QEMU & frens
    I also sometimes run qemu vms. The qemu's manager will be libvirtd, but not sure if I will even use that
    #+begin_src nix
      {
        virtualisation.libvirtd.enable = true;
      }
    #+end_src