[Hyprland] wrong popup positioning with fractional scaling
Describe the bug
A clear and concise description of what the bug is. popups position themself wrong when fractional scaling is used To Reproduce Steps to reproduce the behavior:
- latest hyprland-git and ironbar-git on archlinux
- use my configs
- click on any widget having popup, fe time
- popup positions itself wrong
Expected behavior
A clear and concise description of what you expected to happen. popup positions itself right under the widget System information:
- Distro: Arch Linux
- Compositor: Hyprland
- Ironbar version: ironbar 0.16.0-pre (ironbar-git)
Configuration
Share your bar configuration and stylesheet as applicable:
Config
{
"$schema": "https://f.jstanger.dev/github/ironbar/schema.json",
"anchor_to_edges": true,
"position": "top",
"height": 16,
"popup_gap": 0,
"icon_theme": "Fluent-teal-dark",
"start": [
{
"type": "workspaces",
"all_monitors": false,
"name_map": {
"special:magic": "S"
}
},
{
"type": "launcher",
"favorites": [
"thunar",
"firefox",
"mgba",
"PPSSPPSDL",
"lutris"
],
"show_names": false,
"show_icons": true
}
],
"center": [
{
"type": "clock"
}
],
"end": [
{
"type": "volume",
"format": "{icon} {percentage}%",
"max_volume": 100,
"on_click_right": "amixer -D pipewire sset Master toggle",
"on_scroll_up": "amixer -D pipewire sset Master playback 5%-",
"on_scroll_down": "amixer -D pipewire sset Master playback 5%+",
"icons": {
"volume_high": "",
"volume_medium": "",
"volume_low": "",
"muted": ""
}
},
{
"type": "clipboard",
"max_items": 3,
"on_click_right": "kitty",
"truncate": {
"mode": "end",
"length": 50
}
},
{
"type": "custom",
"class": "power-menu",
"bar": [
{
"type": "button",
"name": "power-btn",
"label": "",
"on_click": "popup:toggle"
}
],
"popup": [
{
"type": "box",
"orientation": "vertical",
"widgets": [
{
"type": "label",
"name": "header",
"label": "Power menu"
},
{
"type": "box",
"widgets": [
{
"type": "button",
"class": "power-btn",
"label": "<span font-size='40pt'> </span>",
"on_click": "!shutdown now"
},
{
"type": "button",
"class": "power-btn",
"label": "<span font-size='40pt'> </span>",
"on_click": "!reboot"
}
]
},
{
"type": "label",
"name": "uptime",
"label": "Uptime: {{30000:uptime -p | cut -d ' ' -f2-}}"
}
]
}
],
"tooltip": "Up: {{30000:uptime -p | cut -d ' ' -f2-}}"
},
{
"type": "upower",
"format": "{percentage}%"
},
{
"type": "notifications",
"show_count": true,
"icons": {
"closed_none": "",
"closed_some": "",
"closed_dnd": "",
"open_none": "",
"open_some": "",
"open_dnd": ""
}
}
]
}
Styles
@define-color color_bg rgba(0, 0, 0, 1);
@define-color color_bg_dark rgba(64, 0, 128, 1);
@define-color color_shadow_active rgba(128, 0, 255, 1);
@define-color color_border rgba(0, 0, 255, 1);
@define-color color_border_active rgba(0, 128, 255, 1);
@define-color color_text rgba(200, 185, 255, 1);
@define-color color_urgent rgba(255, 0, 128, 1);
@define-color color_transparent rgba(0, 0, 0, 0);
/* -- base styles -- */
* {
font-family: JetBrains Mono Nerd Font;
font-size: 16px;
border: none;
border-radius: 0;
}
box, menubar, button, .background {
background-color: @color_bg;
background-image: none;
box-shadow: none;
}
box {
background-color: @color_transparent;
}
button, label {
color: @color_text;
}
button:hover, label:hover {
box-shadow: inset 0 2px @color_shadow_active;
}
.upower:hover .contents {
background-color: @color_transparent;
}
scale trough {
min-width: 1px;
min-height: 2px;
}
#bar {
border-bottom: 1px solid @color_border;
}
.popup {
border: 1px solid @color_border;
padding: 1em;
}
/* -- clipboard -- */
.clipboard {
margin-left: 5px;
font-size: 1.1em;
}
.popup-clipboard .item {
padding-bottom: 0.3em;
border-bottom: 1px solid @color_border;
}
/* -- clock -- */
.clock {
font-weight: bold;
margin-left: 5px;
}
.popup-clock .calendar-clock {
color: @color_text;
font-size: 2.5em;
padding-bottom: 0.1em;
}
.popup-clock .calendar {
background-color: @color_bg;
color: @color_text;
}
.popup-clock .calendar .header {
padding-top: 1em;
border-top: 1px solid @color_border;
font-size: 1.5em;
}
.popup-clock .calendar:selected {
background-color: @color_border_active;
}
/* -- launcher -- */
.launcher .item {
margin-right: 4px;
}
.launcher .ifix examtem:not(.focused):hover {
background-color: @color_bg_dark;
}
.launcher .open {
border-top: 1px solid @color_border;
}
.launcher .focused {
border-top: 2px solid @color_border_active;
}
.launcher .urgent {
border-top-color: @color_urgent;
}
.popup-launcher {
padding: 0;
}
.popup-launcher .popup-item:not(:first-child) {
border-top: 1px solid @color_border;
}
/* -- music -- */
.music:hover * {
background-color: @color_bg_dark;
}
.popup-music .album-art {
margin-right: 1em;
}
.popup-music .icon-box {
margin-right: 0.4em;
}
.popup-music .title .icon, .popup-music .title .label {
font-size: 1.7em;
}
.popup-music .controls *:disabled {
color: @color_border;
}
.popup-music .volume .slider slider {
border-radius: 100%;
}
.popup-music .volume .icon {
margin-left: 4px;
}
.popup-music .progress .slider slider {
border-radius: 100%;
}
/* notifications */
.notifications .count {
font-size: 0.6rem;
background-color: @color_text;
color: @color_bg;
border-radius: 100%;
margin-right: 3px;
margin-top: 3px;
padding-left: 4px;
padding-right: 4px;
opacity: 0.7;
}
/* -- script -- */
.script {
padding-left: 10px;
}
/* -- sys_info -- */
.sysinfo {
margin-left: 10px;
}
.sysinfo .item {
margin-left: 5px;
}
/* -- tray -- */
.tray {
margin-left: 10px;
}
/* -- volume -- */
.popup-volume .device-box {
border-right: 1px solid @color_border;
}
/* -- workspaces -- */
.workspaces .item.focused {
border-top: 1px solid @color_border;
}
/* -- custom: power menu -- */
.popup-power-menu #header {
font-size: 1.4em;
padding-bottom: 0.4em;
margin-bottom: 0.6em;
border-bottom: 1px solid @color_border;
}
.popup-power-menu .power-btn {
border: 1px solid @color_border;
padding: 0.6em 1em;
}
.popup-power-menu #buttons > *:nth-child(1) .power-btn {
margin-right: 1em;
}
Hyprland config
# See https://wiki.hyprland.org/Configuring/Monitors/
# monitor=,2880x1620@120,auto,auto
monitor=,2880x1620,auto,1.5 #,vrr,0,bitdepth,10
monitor=HDMI-A-1,[email protected],auto-up,2.0,bitdepth,10
monitor=WL-1,1920x1080,auto,1.0
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
# Execute your favorite apps at launch
# exec-once = waybar & hyprpaper & firefox
exec-once = ~/.config/hypr/xdg-portal-hyprland.sh
env = XCURSOR_THEME,GoogleDot-Black
env = XCURSOR_SIZE,24
env = HYPRCURSOR_THEME,GoogleDot-Violet
env = HYPRCURSOR_SIZE,24
env = SDL_VIDEODRIVER,wayland
env = PATH,/home/ralen/.cargo/bin:$PATH
exec-once = gsettings set org.gnome.desktop.interface cursor-theme 'GoogleDot-Black'
exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
exec-once = wl-paste
exec-once = wl-copy
exec-once = hyprpm reload -n
exec-once = while :; do swaybg -i /home/ralen/Pictures/Wallpapers/spring2024/spring$(shuf -i 1-11 -n1).png & (sleep $(shuf -i 60-300 -n1) && killall swaybg); done
exec-once = ironbar
exec-once = swaync
exec-once = nm-applet
exec-once = blueman-applet
# Source a file (multi-file configs)
# source = ~/.config/hypr/myColors.conf
# Set programs that you use
$terminal = kitty
$fileManager = thunar
$menu = fuzzel
# $menu = pgrep -x "ags" > /dev/null && ags -t launcher
# Some default env vars.
env = XCURSOR_SIZE,24
env = QT_QPA_PLATFORMTHEME,qt6ct # change to qt6ct if you have that
# env = QT_STYLE_OVERRIDE,qt6ct
env = PATH,/home/ralen/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
kb_layout = lar_dv,cyr_dv
kb_variant =
kb_model =
kb_options = terminate:ctrl_alt_bksp,grp:alt_shift_toggle,lv3:ralt_switch,caps:escape
kb_rules =
follow_mouse = 1
touchpad {
natural_scroll = yes
}
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
}
general {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
gaps_in = 5
gaps_out = 10
gaps_workspaces = 50
border_size = 2
col.active_border = rgba(33ccffee) rgba(9900ffee) 45deg
col.inactive_border = rgba(595959aa)
layout = dwindle
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
allow_tearing = false
}
xwayland {
force_zero_scaling = true
}
decoration {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
rounding = 10
blur {
enabled = true
size = 3
passes = 1
}
drop_shadow = yes
shadow_range = 12
shadow_render_power = 3
col.shadow = rgba(1a1a1aee)
# screen_shader = $HOME/git/.files/.config/hypr/shaders/crt-mod.frag
}
animations {
enabled = yes
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
bezier = linear, 0.0, 0.0, 1.0, 1.0
animation = windows, 1, 7, myBezier
animation = windowsOut, 1, 7, default, popin 80%
animation = border, 1, 10, default
animation = borderangle, 1, 40, linear, loop
animation = fade, 1, 7, default
animation = workspaces, 1, 6, default
}
dwindle {
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = yes # you probably want this
}
master {
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
new_status = master
}
gestures {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
workspace_swipe = on
workspace_swipe_forever = on
}
misc {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers
}
# Example windowrule v1
windowrule = float, ^(thunar)$
windowrule = float, ^(Matplotlib)$
windowrule = float, ^(python3)$
# Example windowrule v2
windowrulev2 = float,class:^(kitty)$,title:^(nvim)$
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
layerrule = blur, gtk-layer-shell
layerrule = ignorezero, gtk-layer-shell
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
$mainMod = SUPER
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = $mainMod, F, exec, xdg-open https://
bind = $mainMod, T, exec, telegram-desktop
bind = $mainMod, RETURN, exec, $terminal
bind = $mainMod, Q, killactive,
bind = $mainMod, C, exec, mate-calc
bind = $mainMod, M, exit,
bind = $mainMod, L, exec, hyprlock || zsh,
bind = $mainMod, E, exec, $fileManager
bind = $mainMod Shift, R, exec, ironbar reload
bind = $mainMod, V, togglefloating,
bind = $mainMod, R, exec, $menu
bind = $mainMod, P, pseudo, # dwindle
bind = $mainMod, J, togglesplit, # dwindle
bind = , Print, exec, grim -g "$(slurp)" - | swappy -f - # take a screenshot
bind = $mainMod, F11, fullscreen
# Volume & brightness
binde = ,XF86AudioMute, exec, amixer sset Master toggle
binde = ,XF86AudioLowerVolume, exec, amixer -D pipewire sset Master playback 5%-
binde = ,XF86AudioRaiseVolume, exec, amixer -D pipewire sset Master playback 5%+
binde = ,XF86MonBrightnessDown, exec, brightnessctl s 5%-
binde = ,XF86MonBrightnessUp, exec, brightnessctl s 5%+
# binde = ,XF86AudioRaiseVolume, exec, amixer -D pipewire sset Master 5%+
# binde = ,XF86AudioLowerVolume, exec, amixer -D pipewire sset Master 5%-
# binde = ,XF86MonBrightnessUp, exec, brightnessctl s 1%+
# binde = ,XF86MonBrightnessDown, exec, brightnessctl s 1%-
# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
bind = $mainMod, right, movefocus, r
bind = $mainMod, up, movefocus, u
bind = $mainMod, down, movefocus, d
# Swap windows with mainMod + SHIFT + arrow keys
bind = $mainMod SHIFT, left, swapwindow, l
bind = $mainMod SHIFT, right, swapwindow, r
bind = $mainMod SHIFT, up, swapwindow, u
bind = $mainMod SHIFT, down, swapwindow, d
# Resize windows with mainMod + CTRL + arrow keys
binde = $mainMod CTRL, right, resizeactive, 20 0
binde = $mainMod CTRL, left, resizeactive, -20 0
binde = $mainMod CTRL, up, resizeactive, 0 -20
binde = $mainMod CTRL, down, resizeactive, 0 20
# Switch workspaces with mainMod + [0-9]
bind = $mainMod, 1, workspace, 1
bind = $mainMod, 2, workspace, 2
bind = $mainMod, 3, workspace, 3
bind = $mainMod, 4, workspace, 4
bind = $mainMod, 5, workspace, 5
bind = $mainMod, 6, workspace, 6
bind = $mainMod, 7, workspace, 7
bind = $mainMod, 8, workspace, 8
bind = $mainMod, 9, workspace, 9
bind = $mainMod, 0, workspace, 10
# Move active window to a workspace with mainMod + SHIFT + [0-9]
bind = $mainMod SHIFT, 1, movetoworkspace, 1
bind = $mainMod SHIFT, 2, movetoworkspace, 2
bind = $mainMod SHIFT, 3, movetoworkspace, 3
bind = $mainMod SHIFT, 4, movetoworkspace, 4
bind = $mainMod SHIFT, 5, movetoworkspace, 5
bind = $mainMod SHIFT, 6, movetoworkspace, 6
bind = $mainMod SHIFT, 7, movetoworkspace, 7
bind = $mainMod SHIFT, 8, movetoworkspace, 8
bind = $mainMod SHIFT, 9, movetoworkspace, 9
bind = $mainMod SHIFT, 0, movetoworkspace, 10
# Example special workspace (scratchpad)
bind = $mainMod, S, togglespecialworkspace, magic
bind = $mainMod SHIFT, S, movetoworkspace, special:magic
# Scroll through existing workspaces with mainMod + scroll
bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow
Additional context
Add any other context about the problem here. if you think this is hyprland issue tell me ill open it there Screenshots If applicable, add screenshots to help explain your problem. wrong positioning
right positioning
Same issue happens on niri. It looks like popup positions are based on integer scale, rather than the used fractional scale.
Yep, looks like wl_output and GTK both only report an integer scale. I don't currently take this into account anyway, but this gets rounded up so a 1.25x scale becomes 2x.
I'll need to write a client for the fractional scaling protocol, which shouldn't be too bad.
Definitely didn't just spend two days implementing the fractional scaling protocol only to find I can't use it, and wl_output gives me the number I need anyway.
Fixed in git :)