{ pkgs , ... }: let inherit (import ../lib.nix { }) mkSimpleTrayService ; audio = pkgs.writeScript "audio" '' #!${pkgs.bash}/bin/bash export PATH=${with pkgs; lib.makeBinPath [ pulseaudio findutils gnugrep ]}:$PATH export MUTEFILE=''${TEMPDIR:-/tmp}/.qtilemute case $1 in mute) newstate=$(( $(cat $MUTEFILE || echo 0 ) ^ 1 )) echo -n $newstate > $MUTEFILE pactl list short sinks | awk '{ print $1 }' | xargs -L1 -I {} pactl set-sink-mute {} $newstate ;; lower) pactl list short sinks | awk '{ print $1 }' | xargs -L1 -I {} pactl set-sink-volume {} -10% ;; raise) pactl list short sinks | awk '{ print $1 }' | xargs -L1 -I {} pactl set-sink-volume {} +10% ;; *) echo Unknown command: $1 exit 1 ;; esac ''; qtileConfig = pkgs.writeScript "qtile_config.py" '' from libqtile.config import Key, Screen, Group, Drag, Click from libqtile.command import lazy from libqtile import layout, bar, widget from libqtile import hook import logging, os logger = logging.getLogger() logger.setLevel(logging.WARN) handler = logging.handlers.RotatingFileHandler( os.path.join(os.getenv('TEMPDIR', default="/tmp"), '.qtilelog'), maxBytes=10240000, backupCount=7 ) handler.setLevel(logging.WARN) logger.addHandler(handler) # @hook.subscribe.screen_change # def restart_on_randr(qtile, ev): # import time # # with open(os.path.join(os.environ['TEMPDIR', default="/tmp"], ".qtilelastrestart"), "w"): # pass # # lastRestart = 0 # with open(os.path.join(os.environ['TEMPDIR', default="/tmp"], ".qtilelastrestart"), "r+") as lastRestartFile: # lastRestartStr = lastRestartFile.read() # if len(lastRestartStr) > 0: # lastRestart = float(lastRestartStr) # # print("screen changed. (last change: %s)" % lastRestart) # # delta=time.time()-lastRestart # if delta > 3: # import subprocess # lastRestartFile.seek(0) # lastRestartFile.write("%s" % time.time()) # lastRestartFile.truncate() # # subprocess.call(["autorandr","-c"]) # qtile.cmd_restart() # else: # print("screen is changing too fast: %s" % delta) # # active_screen = 0 # @hook.subscribe.client_focus # def focus_changed(window): # global active_screen # pass # active_screen = window.group.screen.index # # @hook.subscribe.current_screen_change # def move_widget(): # global active_screen # systray = widget.Systray() # logging.warn("Screen changed to %i" % active_screen) key_super = "mod4" key_alt = "mod1" key_control = "control" keys = [ # https://github.com/qtile/qtile/blob/develop/libqtile/xkeysyms.py Key([key_super], "Return", lazy.spawn("${pkgs.roxterm}/bin/roxterm")), Key([key_super], "backslash", lazy.spawn("${pkgs.roxterm}/bin/roxterm")), Key([key_super], "apostrophe", lazy.spawn("${pkgs.roxterm}/bin/roxterm")), Key([key_super], "r", lazy.spawncmd()), Key([key_super], "w", lazy.window.kill()), Key([key_alt, key_super], "l", lazy.spawn('${pkgs.bash}/bin/sh -c "loginctl lock-session $XDG_SESSION_ID"')), Key([key_alt, key_super], "s", lazy.spawn("${pkgs.systemd}/bin/systemctl suspend")), # Key([key_super, key_control], "r", lazy.restart()), Key([key_super, key_control], "r", lazy.spawn("${pkgs.autorandr}/bin/autorandr -c"), lazy.restart()), Key([key_super, key_control], "q", lazy.shutdown()), # Toggle between different layouts as defined below Key([key_super], "Tab", lazy.next_layout()), # MonadTall keybindings Key([key_super], "h", lazy.layout.left()), Key([key_super], "l", lazy.layout.right()), Key([key_super], "j", lazy.layout.down()), Key([key_super], "k", lazy.layout.up()), Key([key_super, key_control], "h", lazy.layout.shuffle_left()), Key([key_super, key_control], "l", lazy.layout.shuffle_right()), Key([key_super, key_control], "j", lazy.layout.shuffle_down()), Key([key_super, key_control], "k", lazy.layout.shuffle_up()), Key([key_super, key_control], "space", lazy.layout.toggle_split()), Key([key_control, key_alt], "h", lazy.layout.grow_left()), Key([key_control, key_alt], "j", lazy.layout.grow_down()), Key([key_control, key_alt], "k", lazy.layout.grow_up()), Key([key_control, key_alt], "l", lazy.layout.grow_right()), Key([key_super], "n", lazy.layout.normalize()), Key([key_super], "o", lazy.layout.maximize()), # Stack Key([key_super], "h", lazy.layout.previous().when('stack')), Key([key_super], "l", lazy.layout.next().when('stack')), Key([key_super], "j", lazy.layout.up().when('stack')), Key([key_super], "k", lazy.layout.down().when('stack')), Key([key_super, key_control], "j", lazy.layout.shuffle_up().when('stack')), Key([key_super, key_control], "k", lazy.layout.shuffle_down().when('stack')), Key([key_super, key_control], "h", lazy.layout.client_to_previous().when('stack')), Key([key_super, key_control], "l", lazy.layout.client_to_next().when('stack')), # Columns Key([key_super], "h", lazy.layout.left().when('columns')), Key([key_super], "l", lazy.layout.right().when('columns')), Key([key_super], "j", lazy.layout.down().when('columns')), Key([key_super], "k", lazy.layout.up().when('columns')), Key([key_super, key_control], "j", lazy.layout.shuffle_down().when('columns')), Key([key_super, key_control], "k", lazy.layout.shuffle_up().when('columns')), Key([key_super, key_control], "h", lazy.layout.shuffle_left().when('columns')), Key([key_super, key_control], "l", lazy.layout.shuffle_right().when('columns')), # Max Key([key_super], "j", lazy.layout.next()), Key([key_super], "k", lazy.layout.previous()), # Multimedia Keys Key([], "XF86AudioPlay", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause")), Key([], "XF86AudioPrev", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous")), Key([], "XF86AudioNext", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next")), ## Microsoft Comfort Curve specific Key([key_super, "shift"], "XF86TouchpadToggle", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous")), Key([key_alt, key_super], "XF86TouchpadToggle", lazy.spawn("${pkgs.dbus}/bin/dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next")), Key([], "XF86AudioMute", lazy.spawn("${audio} mute")), Key([], "XF86AudioLowerVolume", lazy.spawn("${audio} lower")), Key([], "XF86AudioRaiseVolume", lazy.spawn("${audio} raise")), Key([], "Print", lazy.spawn("${pkgs.flameshot}/bin/flameshot gui")), ] groups = [Group(i) for i in "1234567890"] for i in groups: # super + letter of group = switch to group keys.append( Key([key_super], i.name, lazy.group[i.name].toscreen()) ) # super + shift + letter of group = switch to & move focused window to group keys.append( Key([key_super, key_control], i.name, lazy.window.togroup(i.name)) ) layouts = [ layout.Columns(num_columns=3, border_focus='#00ff00', border_width=2), layout.Max(), # layout.Stack(num_stacks=3, border_focus='#00ff00', border_width=2, autosplit=True, previous_on_rm=True), # layout.Wmii(border_focus='#00ff00'), # layout.MonadTall(ratio=0.6, border_focus='#00ff00'), ] widget_defaults = dict( font='Arial', fontsize=16, padding=3, ) screens_count = 4 screens = [] for i in range(0, screens_count+1): j = i+1 widgets = [ widget.TextBox("Screen %i" % j, name="Screen %i" % j), widget.GroupBox(), widget.WindowName(), widget.Prompt(), widget.CPUGraph(), widget.MemoryGraph(), widget.NetGraph(bandwidth_type='down'), widget.NetGraph(bandwidth_type='up'), widget.Clock(format='%Y-%m-%d %a %I:%M %p'), ] if i is 0: widgets.insert(-1, widget.Systray()) screens.append(Screen(bottom=bar.Bar(widgets, 30))) keys.append(Key([key_super, "shift"], "%i" % (i+1), lazy.to_screen(i))) # subscribe.current_screen_change(func) dgroups_key_binder = None dgroups_app_rules = [] main = None follow_mouse_focus = False bring_front_click = True cursor_warp = False auto_fullscreen = True focus_on_window_activation = "urgent" # Drag floating layouts. mouse = [ Drag([key_super,key_control], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()), Drag([key_super,key_control], "Button2", lazy.window.set_size_floating(), start=lazy.window.get_size()), Click([key_super,key_control], "Button3", lazy.window.disable_floating()) ] floating_layout = layout.Floating() wmname = "LG3D" ''; in { systemd.user = { startServices = true; services = { redshift-gtk = mkSimpleTrayService { execStart = "${pkgs.redshift}/bin/redshift-gtk -v -l 47.6691:9.1698 -t 7000:4500 -m randr"; }; pasystray = mkSimpleTrayService { execStart = "${pkgs.pasystray}/bin/pasystray"; }; cbatticon = mkSimpleTrayService { execStart = "${pkgs.cbatticon}/bin/cbatticon"; }; }; }; services = { gnome-keyring.enable = true; blueman-applet.enable = true; screen-locker = { enable = true; inactiveInterval = 7; lockCmd = "${pkgs.xscreensaver}/bin/xscreensaver-command -lock"; }; xscreensaver.enable = true; network-manager-applet.enable = true; syncthing.enable = true; gpg-agent = { enable = true; enableScDaemon = true; enableSshSupport = true; grabKeyboardAndMouse = true; }; flameshot.enable = true; }; xsession = { enable = true; windowManager.command = "${pkgs.qtile}/bin/qtile -c ${qtileConfig}"; initExtra = '' ${pkgs.autorandr}/bin/autorandr -c ${pkgs.feh}/bin/feh --bg-scale ${pkgs.nixos-artwork.wallpapers.simple-blue}/share/artwork/gnome/nix-wallpaper-simple-blue.png ''; }; home.packages = with pkgs; [ # X Tools/Libraries lightdm qtile xscreensaver gnome3.networkmanagerapplet autorandr arandr gnome3.gnome_themes_standard gnome3.adwaita-icon-theme lxappearance xorg.xcursorthemes pavucontrol ]; }