Hyprland: Hyprland crashes when used with kanshi on NixOS
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 = "3840x2160@59.997002";
position = "0,0";
scale = 2.0;
}
{
criteria = "Dell Inc. DELL S2722QC C77WLD3";
mode = "3840x2160@60.000000";
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 3840x2160@60.000000, 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 3840x2160@60.00Hz, 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 3840x2160@59.997002, 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 3840x2160@60.00Hz, 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 3840x2160@59.997002 position 0,0 scale 2
output "Dell Inc. DELL S2722QC C77WLD3" mode 3840x2160@60.000000position 1920,0 scale 2
output eDP-1 disable
}
hyprctl monitors output
~> hyprctl monitors
Monitor eDP-1 (ID 0):
1920x1080@60.020000 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):
3840x2160@60.000000 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):
3840x2160@59.997002 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
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 2
- Comments: 29 (8 by maintainers)
Can confirm. There is a log of kanshi, probably can clarify smth
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@LU15W1R7H
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
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).
@alexandru0-dev Thank you! I can confirm that the issue is not present when building from the latest commit on the master branch.
@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
@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
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):
But this doesn’t:
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, thedisable
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 theeDP-1-only
profile. Afterhyprctl 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).