Hyprland icon indicating copy to clipboard operation
Hyprland copied to clipboard

Hyprland crashes when used with kanshi on NixOS

Open KarthikNayak opened this issue 1 year ago • 28 comments

Hello, I'm relatively new to NixOS and hyprland. I'm trying to setup kanshi with hyprland so that when I connect my laptop to my monitors, the internal screen is disabled. But this seems to crash hyprland. Attaching the logs here:

@fufexan tagging you since its NixOS related.

Unfortunately I can't make my NixOS config open but this is the kanshi flake

{ config, lib, pkgs, ... }:

{
  services = {
    kanshi = {
      enable = true;
      systemdTarget = "xdg-desktop-portal-hyprland.service";
      profiles = {
        laptop = {
          outputs = [
            {
              criteria = "eDP-1";
            }
          ];
        };
        home = {
          outputs = [
            {
              criteria = "Dell Inc. DELL S2722QC FL7WLD3";
              mode = "[email protected]";
              position = "0,0";
              scale = 2.0;
            }
            {
              criteria = "Dell Inc. DELL S2722QC C77WLD3";
              mode = "[email protected]";
              position = "1920,0";
              scale = 2.0;
            }
            {
              criteria = "eDP-1";
              status = "disable";
            }
          ];
        };
      };
    };
  };
}

My hyprland nix config

{ config, lib, pkgs, ... }:

let
  hyprlandConf = ''
    exec-once=${pkgs.swaybg}/bin/swaybg -m stretch -i $HOME/.config/wall
    exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
    exec-once=systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
    exec-once=${pkgs.networkmanagerapplet}/bin/nm-applet --indicator
    exec-once=${pkgs.waybar}/bin/waybar
    exec-once=${pkgs.blueman}/bin/blueman-applet

    monitor=eDP-1, highres, 0x0, 1.0

    input {
        kb_layout = us
        kb_options = ctrl:nocaps
        follow_mouse = 1

        touchpad {
            natural_scroll = no
        }

        sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
    }

    bind=SUPER SHIFT, P, exec,${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" - | ${pkgs.swappy}/bin/swappy -f - -o ~/Pictures/$(date +%Hh_%Mm_%Ss_%d_%B_%Y).png && notify-send "Saved to ~/Pictures/$(date +%Hh_%Mm_%Ss_%d_%B_%Y).png"
    bind=,XF86AudioLowerVolume,exec,${pkgs.pamixer}/bin/pamixer -d 10
    bind=,XF86AudioRaiseVolume,exec,${pkgs.pamixer}/bin/pamixer -i 10
    bind=,XF86AudioMute,exec,${pkgs.pamixer}/bin/pamixer -t
    bind=,XF86AudioMicMute,exec,${pkgs.pamixer}/bin/pamixer --default-source -t
    bind=,XF86MonBrightnessDown,exec,${pkgs.light}/bin/light -U 10
    bind=,XF86MonBrightnessUP,exec,${pkgs.light}/bin/light -A 10

    general {
        gaps_in = 5
        gaps_out = 5

        border_size=1
        no_border_on_floating = true
        col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
        col.inactive_border = rgba(595959aa)

        layout = dwindle
    }

    decoration {
      rounding = 8
      multisample_edges = true

      active_opacity = 1.0
      inactive_opacity = 1.0

      blur = true
      blur_size = 3
      blur_passes = 3
      blur_new_optimizations = true

      drop_shadow = false
      # drop_shadow = true
      # shadow_ignore_window = true
      # shadow_offset = 2 2
      # shadow_range = 4
      # shadow_render_power = 2
      # col.shadow = 0x66000000

      blurls = gtk-layer-shell
      # blurls = waybar
      blurls = lockscreen
    }

    animations {
      enabled = true
      # enabled = true
      # bezier = overshot, 0.05, 0.9, 0.1, 1.05
      # bezier = smoothOut, 0.36, 0, 0.66, -0.56
      # bezier = smoothIn, 0.25, 1, 0.5, 1

      # animation = windows, 1, 5, overshot, slide
      # animation = windowsOut, 1, 4, smoothOut, slide
      # animation = windowsMove, 1, 4, default
      # animation = border, 1, 10, default
      # animation = fade, 1, 10, smoothIn
      # animation = fadeDim, 1, 10, smoothIn
      # animation = workspaces, 1, 6, default
    }

    dwindle {
      no_gaps_when_only = false
      pseudotile = true # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
      preserve_split = true # you probably want this
    }

    windowrule = float, file_progress
    windowrule = float, confirm
    windowrule = float, dialog
    windowrule = float, download
    windowrule = float, notification
    windowrule = float, error
    windowrule = float, splash
    windowrule = float, confirmreset
    windowrule = float, title:Open File
    windowrule = float, title:branchdialog
    windowrule = float, Lxappearance
    windowrule = float, Rofi
    windowrule = animation none,Rofi
    windowrule = float, viewnior
    windowrule = float, Viewnior
    windowrule = float, feh
    windowrule = float, pavucontrol-qt
    windowrule = float, pavucontrol
    windowrule = float, file-roller
    windowrule = fullscreen, wlogout
    windowrule = float, title:wlogout
    windowrule = fullscreen, title:wlogout
    windowrule = idleinhibit focus, mpv
    windowrule = idleinhibit fullscreen, firefox
    windowrule = float, title:^(Media viewer)$
    windowrule = float, title:^(Volume Control)$
    windowrule = float, title:^(Picture-in-Picture)$
    windowrule = size 800 600, title:^(Volume Control)$
    windowrule = move 75 44%, title:^(Volume Control)$

    bind = SUPER SHIFT, O, exec, ${pkgs.swaylock}/bin/swaylock
    bind = SUPER, Return, exec, ${pkgs.alacritty}/bin/alacritty
    bind = SUPER, E, exec, thunar
    bind = SUPER, D, exec, ${pkgs.rofi}/bin/rofi -show drun -theme ~/.config/rofi/global/rofi.rasi
    #bind = SUPER, D, exec, "killall rofi; and ${pkgs.rofi}/bin/rofi -show drun"
    bind = SUPER, escape, exec, wlogout --protocol layer-shell -b 5 -T 400 -B 400
    bind = SUPER, Slash, exec, dunstctl close
    bind = SUPER, Period, exec, dunstctl action
    bind = SUPER, Grave, exec, dunstctl history-pop
    bind = SUPER, Q, killactive,
    #bind = SUPER, E, exec, ${pkgs.pcmanfm}/bin/pcmanfm
    bind = SUPER, T, exec, ${pkgs.emacs}/bin/emacsclient -c

    bind = SUPER SHIFT, E, exit
    bind = SUPER SHIFT, Q, killactive
    bind = SUPER, F, fullscreen,
    bind = SUPER, Space, togglefloating,
    bind = SUPER, P, pseudo, # dwindle
    bind = SUPER, S, togglesplit, # dwindle
    bind = SUPER, TAB, workspace, previous
    bind = SUPER SHIFT, Comma, movecurrentworkspacetomonitor, -1
    bind = SUPER SHIFT, Period, movecurrentworkspacetomonitor, +1

    bind = SUPER, left, movefocus, l
    bind = SUPER, right, movefocus, r
    bind = SUPER, up, movefocus, u
    bind = SUPER, down, movefocus, d

    bind = SUPER, J, movefocus, l
    bind = SUPER, semicolon, movefocus, r
    bind = SUPER, L, movefocus, u
    bind = SUPER, K, movefocus, d

    bind = SUPER SHIFT, left, movewindow, l
    bind = SUPER SHIFT, right, movewindow, r
    bind = SUPER SHIFT, up, movewindow, u
    bind = SUPER SHIFT, down, movewindow, d

    bind = SUPER SHIFT, H, movewindow, l
    bind = SUPER SHIFT, L, movewindow, r
    bind = SUPER SHIFT, K, movewindow, u
    bind = SUPER SHIFT, J, movewindow, d

    bind = SUPER CTRL, left, resizeactive, -20 0
    bind = SUPER CTRL, right, resizeactive, 20 0
    bind = SUPER CTRL, up, resizeactive, 0 -20
    bind = SUPER CTRL, down, resizeactive, 0 20

    bind= SUPER, w, togglegroup
    bind= SUPER, z, changegroupactive

    bind = SUPER, c, togglespecialworkspace
    bind = SUPERSHIFT, c, movetoworkspace, special

    bind = SUPER, 1, workspace, 1
    bind = SUPER, 2, workspace, 2
    bind = SUPER, 3, workspace, 3
    bind = SUPER, 4, workspace, 4
    bind = SUPER, 5, workspace, 5
    bind = SUPER, 6, workspace, 6
    bind = SUPER, 7, workspace, 7
    bind = SUPER, 8, workspace, 8
    bind = SUPER, 9, workspace, 9
    bind = SUPER, 0, workspace, 10
    bind = SUPER ALT, up, workspace, e+1
    bind = SUPER ALT, down, workspace, e-1

    bind = SUPER SHIFT, 1, movetoworkspace, 1
    bind = SUPER SHIFT, 2, movetoworkspace, 2
    bind = SUPER SHIFT, 3, movetoworkspace, 3
    bind = SUPER SHIFT, 4, movetoworkspace, 4
    bind = SUPER SHIFT, 5, movetoworkspace, 5
    bind = SUPER SHIFT, 6, movetoworkspace, 6
    bind = SUPER SHIFT, 7, movetoworkspace, 7
    bind = SUPER SHIFT, 8, movetoworkspace, 8
    bind = SUPER SHIFT, 9, movetoworkspace, 9
    bind = SUPER SHIFT, 0, movetoworkspace, 10

    bindm = SUPER, mouse:272, movewindow
    bindm = SUPER, mouse:273, resizewindow
    bind = SUPER, mouse_down, workspace, e+1
    bind = SUPER, mouse_up, workspace, e-1
  '';
in
{
  xdg.configFile."hypr/hyprland.conf".text = hyprlandConf;

  programs.swaylock.settings = {
    ignore-empty-password = true;
	  show-failed-attempts  = true;
	  indicator-caps-lock  = true;
	  image = "$HOME/.config/wall";
	  scaling = "fill";
	  font = "Iosevka Nerd Font";
	  font-size = 45;
	  indicator-radius = 170;
	  indicator-thicknes = 15;
	  bs-hl-color  = "94E2D5";
	  key-hl-color  = "94E2D5";
	  caps-lock-bs-hl-color  = "94E2D5";
	  caps-lock-key-hl-color  = "94E2D5";
	  inside-color = "1E1E2E";
	  inside-clear-color = "1E1E2E";
	  inside-caps-lock-color = "1E1E2E";
	  inside-ver-color = "1E1E2E";
	  inside-wrong-color = "1E1E2E";
	  line-color = "00000000";
	  line-clear-color = "00000000";
	  line-caps-lock-color = "00000000";
	  line-ver-color = "00000000";
	  line-wrong-color = "00000000";
	  ring-color = "FAB387";
	  ring-clear-color = "F9E2AF";
	  ring-caps-lock-color = "FAB387";
	  ring-ver-color = "A6E3A1";
	  ring-wrong-color = "F38BA8";
	  separator-color = "00000000";
	  text-color  = "94E2D5";
	  text-clear-color  = "94E2D5";
	  text-ver-color  = "94E2D5";
	  text-wrong-color  = "94E2D5";
	  text-caps-lock-color = "94E2D5";
  };

  services.swayidle = {
    enable = true;
    events = [
      { event = "before-sleep"; command = "${pkgs.swaylock}/bin/swaylock -f"; }
      { event = "lock"; command = "lock"; }
    ];
    timeouts = [
      { timeout = 300; command = "${pkgs.swaylock}/bin/swaylock -f";}
      { timeout = 480; command = "systemctl suspend"; }
    ];
    systemdTarget = "xdg-desktop-portal-hyprland.service";
  };
}

Hyprland crash logo

--------------------------------------------
   Hyprland Crash Report
--------------------------------------------
I don't feel so good...

Hyprland received signal 6 (Aborted)

System info:
	System name: Linux
	Node name: personal
	Release: 6.2.6
	Version: #1-NixOS SMP PREEMPT_DYNAMIC Mon Mar 13 09:26:43 UTC 2023

GPU:
	04:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Lucienne [1002:164c] (rev c1) (prog-if 00 [VGA controller])


os-release:
	BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
	BUILD_ID="23.05.20230315.ac718d0"
	DOCUMENTATION_URL="https://nixos.org/learn.html"
	HOME_URL="https://nixos.org/"
	ID=nixos
	LOGO="nix-snowflake"
	NAME=NixOS
	PRETTY_NAME="NixOS 23.05 (Stoat)"
	SUPPORT_URL="https://nixos.org/community.html"
	VERSION="23.05 (Stoat)"
	VERSION_CODENAME=stoat
	VERSION_ID="23.05"
	


Backtrace:
	#0 | Hyprland() [0x49a69d]
			#1 | Hyprland() [0x515e6f]
			#2 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x3dbf0) [0x7f561903dbf0]
			#3 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x8abc7) [0x7f561908abc7]
			#4 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(raise+0x16) [0x7f561903db46]
			#5 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(abort+0xd7) [0x7f56190284b5]
			#6 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x283d9) [0x7f56190283d9]
			#7 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x367b6) [0x7f56190367b6]
			#8 | /nix/store/wflz2jwax6pirbr0gf25i4cwmcm9z4j7-wlroots-hyprland-hidpi-2023-03-02_5ae17de/lib/libwlroots.so.12(+0x6b2f3) [0x7f5619c9d2f3]
			#9 | /nix/store/wflz2jwax6pirbr0gf25i4cwmcm9z4j7-wlroots-hyprland-hidpi-2023-03-02_5ae17de/lib/libwlroots.so.12(wlr_output_damage_attach_render+0x3d) [0x7f5619cbdbad]
			#10 | Hyprland() [0x514391]
			#11 | Hyprland() [0x4b7c7b]
			#12 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_signal_emit_mutable+0x7c) [0x7f5619d508fc]
			#13 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_event_loop_dispatch_idle+0x1b) [0x7f5619d526fb]
			#14 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_event_loop_dispatch+0xfa) [0x7f5619d5281a]
			#15 | /nix/store/q1h62pjh94fanmw6l3vi2daysny2mwr0-wayland-1.21.0/lib/libwayland-server.so.0(wl_display_run+0x25) [0x7f5619d50335]
			#16 | Hyprland() [0x42e26c]
			#17 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(+0x2924e) [0x7f561902924e]
			#18 | /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(__libc_start_main+0x89) [0x7f5619029309]
			#19 | Hyprland() [0x444375]
		

Log tail:
[LOG] Framebuffer created, status 36053
[LOG] LayerSurface 3290d60 destroyed
[LOG] Callback 328cc78 -> 328cc70, layerSurface removed.
[LOG] Callback 328cb40 -> 328cb38, layerSurface removed.
[LOG] Callback 328cba8 -> 328cba0, layerSurface removed.
[LOG] Callback 328cc10 -> 328cc08, layerSurface removed.
[LOG] Callback 328cce0 -> 328ccd8, layerSurface removed.
[LOG] LayerSurface 32b3c40 arranged: x: 0 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor eDP-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] LayerSurface 3047be0 unmapped
[LOG] Framebuffer created, status 36053
[LOG] LayerSurface 3047be0 destroyed
[LOG] Callback 32b3e38 -> 32b3e30, layerSurface removed.
[LOG] Callback 32b3d00 -> 32b3cf8, layerSurface removed.
[LOG] Callback 32b3d68 -> 32b3d60, layerSurface removed.
[LOG] Callback 32b3dd0 -> 32b3dc8, layerSurface removed.
[LOG] Callback 32b3ea0 -> 32b3e98, layerSurface removed.
[LOG] Monitor eDP-1 layers arranged: reserved: 0.000000 0.000000 0.000000 0.000000
[LOG] Removed monitor eDP-1!
[LOG]  [hookSystem] New hook event registered: monitorRemoved
[LOG] moveWorkspaceToMonitor: Moving 1 to monitor 1
[LOG] moveWorkspaceToMonitor: Plugging gap with new 4
[LOG] moveWorkspaceToMonitor: Plugging gap with existing 4
[LOG] Changed to workspace 1
[LOG]  [hookSystem] New hook event registered: workspace
[LOG] Changed to workspace 4
[LOG] moveWorkspaceToMonitor: SWITCHINGISACTIVE, active 2 -> 1
[LOG]  [hookSystem] New hook event registered: moveWorkspace
[LOG] Destroying workspace ID 4
[LOG]  [hookSystem] New hook event registered: destroyWorkspace
[LOG] Applying monitor rule for HDMI-A-1
[LOG] Monitor HDMI-A-1: requested [email protected], found available mode: 3840x2160@60000mHz, applying.
[LOG] Monitor HDMI-A-1 -> destroyed all render data
[LOG] LayerSurface 32ae180 arranged: x: 1920 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 32890e0 arranged: x: 1920 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor HDMI-A-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] Monitor HDMI-A-1 data dump: res [email protected], scale 2.00, transform 0, pos 1920x0, 10b 0
[LOG] LayerSurface 32ae180 arranged: x: 1920 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 32890e0 arranged: x: 1920 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor HDMI-A-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] Applying monitor rule for DP-1
[LOG] Monitor DP-1: requested [email protected], found available mode: 3840x2160@59997mHz, applying.
[LOG] Monitor DP-1 -> destroyed all render data
[LOG] LayerSurface 2d895b0 arranged: x: 0 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 328e570 arranged: x: 0 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor DP-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000
[LOG] Monitor DP-1 data dump: res [email protected], scale 2.00, transform 0, pos 0x0, 10b 0
[LOG] LayerSurface 2d895b0 arranged: x: 0 y: 0 w: 1920 h: 41 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] LayerSurface 328e570 arranged: x: 0 y: 0 w: 1920 h: 1080 with margins: t: 0 l: 0 r: 0 b: 0
[LOG] Monitor DP-1 layers arranged: reserved: 0.000000 41.000000 0.000000 0.000000

Kanshi config

profile home {
  output eDP-1 enable mode 1920x1200 position 0,0 scale 1
}

profile home {
	output "Dell Inc. DELL S2722QC FL7WLD3" mode [email protected] position 0,0 scale 2
	output "Dell Inc. DELL S2722QC C77WLD3" mode [email protected] 1920,0 scale 2
	output eDP-1 disable
}

hyprctl monitors output

~> hyprctl monitors
Monitor eDP-1 (ID 0):
	[email protected] at 0x0
	description: LG Display 0x0683 (eDP-1)
	make: LG Display
	model: 0x0683
	serial:
	active workspace: 3 (3)
	reserved: 0 41 0 0
	scale: 1.00
	transform: 0
	focused: no
	dpmsStatus: 1
	vrr: 0

Monitor HDMI-A-1 (ID 1):
	[email protected] at 1920x0
	description: Dell Inc. DELL S2722QC C77WLD3 (HDMI-A-1)
	make: Dell Inc.
	model: DELL S2722QC
	serial: C77WLD3
	active workspace: 2 (2)
	reserved: 0 41 0 0
	scale: 1.50
	transform: 0
	focused: yes
	dpmsStatus: 1
	vrr: 0

Monitor DP-1 (ID 2):
	[email protected] at 5760x0
	description: Dell Inc. DELL S2722QC FL7WLD3 (DP-1)
	make: Dell Inc.
	model: DELL S2722QC
	serial: FL7WLD3
	active workspace: 4 (4)
	reserved: 0 41 0 0
	scale: 1.50
	transform: 0
	focused: no
	dpmsStatus: 1
	vrr: 0

KarthikNayak avatar Jun 26 '23 06:06 KarthikNayak

I don't understand, do you use kanshi through Home Manager or manually write its config file? The one you sent (code block 3) does not correspond to something that would be generated by Home Manager using the code provided in (code block 1). Also, it seems to have a typo in the second monitor's config.

fufexan avatar Jun 26 '23 19:06 fufexan

I don't understand, do you use kanshi through Home Manager or manually write its config file? The one you sent (code block 3) does not correspond to something that would be generated by Home Manager using the code provided in (code block 1). Also, it seems to have a typo in the second monitor's config.

If you're referring to the name of the profiles, it was just me testing out stuff with two laptops. So they're the same, let me edit it to avoid confusion (sorry in the first place, didn't notice it).

Also, it seems to have a typo in the second monitor's config.

Hmm where ? Either ways I was trying out things to make it work. The weird part is that hyprland shouldn't crash right?

KarthikNayak avatar Jun 26 '23 21:06 KarthikNayak

profile home {
	output "Dell Inc. DELL S2722QC FL7WLD3" mode [email protected] position 0,0 scale 2
>	output "Dell Inc. DELL S2722QC C77WLD3" mode [email protected] 1920,0 scale 2
	output eDP-1 disable
}

Refresh rate and positon are not space separated here, not sure if kanshi can still parse it.

Anyway, I've used kanshi with Hyprland in the past with no issues, so no, it shouldn't crash. I'll test again tomorrow if I have time and report back.

fufexan avatar Jun 26 '23 21:06 fufexan

profile home {
	output "Dell Inc. DELL S2722QC FL7WLD3" mode [email protected] position 0,0 scale 2
>	output "Dell Inc. DELL S2722QC C77WLD3" mode [email protected] 1920,0 scale 2
	output eDP-1 disable
}

Refresh rate and positon are not space separated here, not sure if kanshi can still parse it.

Yeah this is my bad in copying, like I said I was playing around to make it work. The actual config is generated by HomeManager Knanshi and wouldn't have this issue.

Anyway, I've used kanshi with Hyprland in the past with no issues, so no, it shouldn't crash. I'll test again tomorrow if I have time and report back.

What do you use now? I'm not stuck to kanshi, but it has been the best way to switch from dock to standalone mode for my laptop! But anyways thanks for your time and sorry for the confusion.

KarthikNayak avatar Jun 27 '23 09:06 KarthikNayak

I don't use external monitors much nowadays so I ditched it and just use anyrun's randr mode which lets me position/mirror monitors in Hyprland. image

fufexan avatar Jun 27 '23 09:06 fufexan

I don't use external monitors much nowadays so I ditched it and just use anyrun's randr mode which lets me position/mirror monitors in Hyprland.

Neat, but I think this wouldn't work for me much, I keep switching between the two modes and Kanshi works great for me. Happy to help with more logs or such if needed! Until which, I'll have to disable Kanshi :D

KarthikNayak avatar Jun 27 '23 09:06 KarthikNayak

Ok I've re-enabled kanshi, seems to work. What doesn't seem to work in your case is disabling the internal screen. I will try that now.

fufexan avatar Jun 27 '23 20:06 fufexan

With this config, it all seems to work fine up until disconnecting all remaining active monitors.

  services.kanshi = {
    enable = true;
    profiles = {
      undocked = {
        outputs = [
          {
            criteria = "eDP-1";
            position = "0,0";
          }
        ];
      };
      docked-all = {
        outputs = [
          {
            criteria = "eDP-1";
            position = "1366,0";
          }
          {
            criteria = "DP-1";
            position = "0,0";
          }
          {
            criteria = "DP-2";
            position = "1600,0";
          }
        ];
      };

      docked1 = {
        outputs = [
          {
            criteria = "eDP-1";
            status = "disable";
          }
          {
            criteria = "DP-1";
            position = "0,0";
          }
        ];
      };

      docked2 = {
        outputs = [
          {
            criteria = "eDP-1";
            status = "disable";
          }
          {
            criteria = "DP-2";
            position = "0,0";
          }
        ];
      };
    };
    systemdTarget = "graphical-session.target";
  };

Tested the docked2 profile. After unplugging the external screen, kanshi didn't re-check the active profile and left the internal screen disabled, so Hyprland crashed with no active output.

fufexan avatar Jun 27 '23 20:06 fufexan

I have a similar issue when using binds to enable/disable my laptop's internal display on open/close respectively. Display correctly turns off and on, but if I disconnect the external monitor while the laptop lid is still closed, Hyprland crashes and I get thrown back to the tty. Kanshi seems to be the proper way to do this, but it's unfortunate that it faces a similar issue.

This seems likely to be the same issue as the one experienced when using Kanshi.

Here's how I have my scripts configured in NixOS:

let

  # when lid closed, if at least one external display connected, disable internal display
  closeLid = pkgs.writeShellScriptBin "closeLid" ''
    if [ $(hyprctl monitors | wc -l) -gt 15 ] && [ ! -z "$(hyprctl monitors |  grep eDP-1)" ]; then
      hyprctl keyword monitor "eDP-1, disable"
    fi
  '';

  # when lid opened, if internal display disabled, re-enable display and reload Hyprland
  openLid = pkgs.writeShellScriptBin "openLid" ''
    if [ -z "$(hyprctl monitors |  grep eDP-1)" ]; then
      hyprctl keyword monitor "eDP-1, preferred, auto, 1"
      systemctl --user restart waybar
      hyprctl reload
    fi
  '';

in {
  wayland.windowManager.hyprland = {
    ...

    extraConfig = ''
      ...

      bindl=,switch:on:Lid Switch,exec,${closeLid}/bin/closeLid
      bindl=,switch:off:Lid Switch,exec,${openLid}/bin/openLid
    '';
  };
}

omernaveedxyz avatar Jun 30 '23 08:06 omernaveedxyz

I think the problem could easily be solved by Hyprland. It would only have to enable any remaining monitor when all the others are gone. Should only crash when there are no displays left (not disabled).

fufexan avatar Jun 30 '23 08:06 fufexan

Weirdly, I had other issues with NixOS and moved to Arch for the time-being and now Hyprland and Kanshi work without any issues.

From my side, I won't be able to test it anymore with NixOS and might come back to this when I have more time to setup NixOS, the issue can be closed, unless someone else has the same issue.

KarthikNayak avatar Jun 30 '23 09:06 KarthikNayak

Weirdly, I had other issues with NixOS and moved to Arch for the time-being and now Hyprland and Kanshi work without any issues.

It's surprising to me that on arch you don't experience these issues. This suggests that it is NixOS specific...

It's probably not home-manager as I am only installing kanshi through home-manager, but the configuration is done through a non-generated kanshi config file.

home.packages = [ pkgs.kanshi ]

The config file looks like this ~/.config/kanshi

profile {
  output eDP-1 enable
}

profile {
  output eDP-1 disable
  output "Samsung Electric Company U28H75x HTPJ700579" enable scale 1.5
}

When disconnecting the external monitor, the internal monitor doesn't turn on again and after interacting with hyprland (switching workspaces) hyprland crashes.

luiswirth avatar Jul 23 '23 20:07 luiswirth

Interesting, but I have no clue how to debug this.

fufexan avatar Jul 24 '23 18:07 fufexan

When disconnecting the external monitor, the internal monitor doesn't turn on again and after interacting with hyprland (switching workspaces) hyprland crashes.

Can confirm. There is a log of kanshi, probably can clarify smth

Jul 25 19:27:42 thinkpad-x1-gen9 systemd[4311]: Started Dynamic output configuration.

-------- INITIAL CONFIGURATION, NOTHING CONNECTED TO LAPTOP ----------
Jul 25 19:27:42 thinkpad-x1-gen9 kanshi[4501]: applying profile 'laptopOnly'
Jul 25 19:27:42 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'eDP-1' on connected head 'eDP-1'
Jul 25 19:27:42 thinkpad-x1-gen9 kanshi[4501]: configuration for profile 'laptopOnly' applied

-------- PLUG IN EXTERNAL MONITOR ----------
Jul 25 19:29:23 thinkpad-x1-gen9 kanshi[4501]: applying profile 'withDellDisplay'
Jul 25 19:29:23 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'Dell Inc. DELL U2723QE JSJ91P3' on connected head 'DP-3'
Jul 25 19:29:23 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'eDP-1' on connected head 'eDP-1'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: configuration for profile 'withDellDisplay' cancelled, retrying
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: applying profile 'withDellDisplay'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'Dell Inc. DELL U2723QE JSJ91P3' on connected head 'DP-3'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: applying profile output 'eDP-1' on connected head 'eDP-1'
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: configuration for profile 'withDellDisplay' applied
Jul 25 19:29:24 thinkpad-x1-gen9 kanshi[4501]: no profile matched

-------- DISCONNECT MONITOR ----------
Jul 25 21:09:49 thinkpad-x1-gen9 kanshi[4501]: no profile matched
Jul 25 21:09:58 thinkpad-x1-gen9 kanshi[4501]: no profile matched

Moreover, when I run kanshi after e-DP is turned off it prints: no profile matched seems like hyprland not report that output if it already disabled. I guess hyprland not reports turned off outputs and therefore kanshi can't detect e-DP output after external monitor disconnect

❯ hyprctl monitors
Monitor DP-3 (ID 1):
	[email protected] at 0x0
	description: Dell Inc. DELL U2723QE JSJ91P3 (DP-3)
	make: Dell Inc.
	model: DELL U2723QE
	serial: JSJ91P3
	active workspace: 3 (3)
	special workspace: 0 ()
	reserved: 0 34 0 0
	scale: 1.00
	transform: 0
	focused: yes
	dpmsStatus: 1
	vrr: 0
	```

pltanton avatar Jul 25 '23 21:07 pltanton

@pltanton Thanks for the insight.

It seems that this is a general problem in how hyprland handles monitors. This has nothing to do with kanshi in particular.

The problem is that when disabling a monitor, there is no way (I know of) to reenable it again, as hyprland doesn't list this monitor anymore.

Look at this

> hyprctl monitors
Monitor eDP-1 (ID 0):
	[email protected] at 0x0
	description: Samsung Display Corp. 0x4165 (eDP-1)
	make: Samsung Display Corp.
	model: 0x4165
	serial:
	active workspace: 1 (1)
	special workspace: 0 ()
	reserved: 0 0 0 35
	scale: 2.00
	transform: 0
	focused: no
	dpmsStatus: 1
	vrr: 0

Monitor DP-2 (ID 1):
	[email protected] at 3840x0
	description: Samsung Electric Company U28H75x HTPJ700579 (DP-2)
	make: Samsung Electric Company
	model: U28H75x
	serial: HTPJ700579
	active workspace: 2 (2)
	special workspace: 0 ()
	reserved: 0 0 0 35
	scale: 1.50
	transform: 0
	focused: yes
	dpmsStatus: 1
	vrr: 0

> hyprctl keyword monitor "eDP-1,disable"
ok

> hyprctl monitors
Monitor DP-2 (ID 1):
	[email protected] at 3840x0
	description: Samsung Electric Company U28H75x HTPJ700579 (DP-2)
	make: Samsung Electric Company
	model: U28H75x
	serial: HTPJ700579
	active workspace: 2 (2)
	special workspace: 0 ()
	reserved: 0 0 0 35
	scale: 1.50
	transform: 0
	focused: yes
	dpmsStatus: 1
	vrr: 0

> hyprctl keyword monitor "eDP-1,enable"
Err: stoi

luiswirth avatar Jul 29 '23 13:07 luiswirth

The only way I know is to run hyprctl reload

pltanton avatar Jul 29 '23 16:07 pltanton

This behavior is imho expected on Hyprland: https://wiki.hyprland.org/Configuring/Monitors/#disabling-a-monitor .

To disable output without removing it from Hyprland, one should use DPMS instead. Not sure how to achieve that with kanshi though. You'd probably have to leverage the exec directive.

jficz avatar Aug 11 '23 09:08 jficz

@jficz DPMS is not what we want here, because this only turns the screen off, without actually removing the monitor logically. All workspaces stay on the turned off screen.

I'm inclined to disagree that this is how hyprland should behave. It should still be possible to re-enable the monitor and bring it back.

Also kanshi works through the wlr-output-management protocol. Apparently there is a discrepancy how kanshi and hyprland understanding this protocol.

luiswirth avatar Aug 13 '23 12:08 luiswirth

Good point. Didn't realize how DPMS behaves.

I didn't mean to infer how Hyprland should work, I was merely suggesting that the current behavior is expected given Hyprland "specs".

I did a naive test and it seems that kanshi can actually enable a monitor that has been previously disabled but not under all circumstances. My tests (eDP-1 and DP-1 are connected at the beginning, I'm using kanshi as a user systemd service):

This brings a disabled monitor back up as long as proper profile exists in kanshi, works for both monitors (not at the same time):

hyprctl keyword monitor 'DP-1,disable'
systemctl --user restart kanshi

But this doesn't:

hyprctl keyword monitor 'DP-1,disable'
<disconnect DP-1 physically (USB-C dock in my case)>
<connect it back>

The monitor doesn't come back up, even if kanshi is restarted, until hyprctl reload is executed. That is suboptimal but at least consistently reproducible. According to kanshi logs, the disable command doesn't register with kanshi and after DP-1 is disabled, the physical disconnect doesn't register with kanshi either. It is only when I reconnect the dock again when kanshi pick it up but even then, it doesn't see DP-1 and just applies the eDP-1-only profile. After hyprctl reload is executed, kanshi picks up the correct config on its own.

If the disabled monitor in the latter case is eDP-1, Hyprland crashes*)

I have no solid knowledge how any of kanshi, Hyprland and wlr protocols work so I'm not going to draw any conclusions here, just offering an observation.

This is definitely a bug, Hyprland shouldn't crash. It should, at least, shut down gracefully but somehow I feel that if the discrepancy between the two above described cases is understood, the fix could possibly be inferred, though it could be in kanshi and not Hyprland. Or both.

edit: *) eDP-1 screen is just off after disconnect but nothing happens until I actually reconnect DP-1 back. It is only then when Hyprland crashes. Same if I use similar kanshi profile as OP (that is, eDP-1 off when other screens exist).

jficz avatar Aug 13 '23 13:08 jficz

It should still be possible to re-enable the monitor and bring it back.

It's possible with wlr-randr at least.

fufexan avatar Aug 13 '23 15:08 fufexan

It should still be possible to re-enable the monitor and bring it back.

It's possible with wlr-randr at least.

with the same limitations as kanshi has, as I described above

Just tested it, wlr-randr doesn't see the output if disabled, disconnected and then reconnected again, exactly the same as kanshi.

jficz avatar Aug 16 '23 15:08 jficz

@LU15W1R7H

I'm inclined to disagree that this is how hyprland should behave. It should still be possible to re-enable the monitor and bring it back.

This comment posted in another issue might be relevant to this: https://github.com/hyprwm/Hyprland/issues/1274#issuecomment-1573388218

Seems like "out of spec" behaviour

skiletro avatar Aug 21 '23 23:08 skiletro

After going through other discussions I need to revisit my previous opinion. I still think that this is "on spec" behavior for Hyprland (because it is documented as such) but is indeed "out of spec" relative to wlr protocols and the fix imho needs to be introduced on Hyprland side.

However, it's off-topic for this specific issue as this issue, unrelated to Kanshi, requires a different kind of fix - the fallback kind of fix. Imo something like this: if no more outputs are enabled, try to enable any output available regardless of their state and only fail [not crash] when there is no more outputs that can be enabled. Or possibly do not even fail, just log the situation to the console so the user can solve the issue by connecting a new monitor for example. Or, if a no-crash-fail path is taken, don't even try to enable available displays, just log the issue and wait, because that may in fact be what the user intended by their configuration. Not sure though if this situation is supported by wlr. Is it possible to lose all heads and still have active session in Wayland?

On the other hand, if #1274 is fixed "properly", this issue may no longer be too relevant so long as Kanshi has enough time to enable the previously disabled display before Hyprland crashes due to lack of displays.

jficz avatar Aug 22 '23 07:08 jficz

i'm still having the same issue, any way of "fixing it"?

  • using hyprctrl: disabling the monitor and re-enabling works
  • using kanshi: disabling the monitor works, but re-enabling doesn't works as expected.

My findings:

the output wlr-randr of kanshi vs hyprctrl when disabling the monitor are different

// hyprctl keyword monitor "eDP-1,disable"
eDP-1 ....
  Enabled: no

when using kanshi the enable attribute is set to yes

@vaxerski @fufexan any idea why this behaviour? shouldn't both be using wlr-output-management? EDIT: with kanshi 1.5.0 it works and it doesn't crash. THO to time to time my laptop display doesn't re-enable itself but it doesn't crash, in fact connecting the hdmi back again i still have my hyprland session up.

alexandru0-dev avatar Jan 21 '24 00:01 alexandru0-dev

@alexandru0-dev weird. I am on Kanshi 1.5.1, but the issue persists. It doesn't seem like it is a Kanshi bug, but I might be wrong

AlexNabokikh avatar Feb 21 '24 05:02 AlexNabokikh

@AlexNabokikh try building hyprland from the last master as at some point it was introduced a regression which broke this again and then got it fixed recently

U can check: https://github.com/hyprwm/Hyprland/issues/4725 https://github.com/hyprwm/Hyprland/issues/4728

alexandru0-dev avatar Feb 21 '24 05:02 alexandru0-dev

@AlexNabokikh if u are using nixos (I seen your config in your repos) use the hyprland flake, it's highly recommended (u can follow the wiki)

This will also allow you to build from master or a pinned tag/commit

alexandru0-dev avatar Feb 21 '24 06:02 alexandru0-dev

@alexandru0-dev Thank you! I can confirm that the issue is not present when building from the latest commit on the master branch.

AlexNabokikh avatar Feb 21 '24 11:02 AlexNabokikh

Just to add a datapoint: on Fedora 39 and Hyprland v0.35.0 starting Kanshi would crash Hyprland. After uprgrading to Hyprland 81fe2ae Kanshi works.

anderso avatar Feb 26 '24 14:02 anderso