--- Possible Effects on Windows --- Static Efects local function float() return { float = true } end local function tile() return { tile = true } end local function fullscreen() return { fullscreen = true } end local FullScreenState = { NONE = 0, MAXMIMIZE = 1, FULLSCREEN = 2, MAXIMIZE_AND_FULLSCREEN = 3, } local function fullscreen_state(internal, client) local internal = internal or FullScreenState.NONE local client = client or FullScreenState.NONE return { fullscreen_state = string.format("%d %d", internal, client) } end local function move(location) return { move = location } end local function size(width, height) return { size = {width, height} } end local function center() return { center = true } end local function pseudo() return { pseudo = true } end local function monitor(monitor, silent) if silent then monitor = monitor .. " silent" end return { monitor = monitor } end local function workspace(workspace, silent) if silent then workspace = workspace .. " silent" end return { workspace = workspace } end local function no_initial_focus() return { no_initial_focus = true } end local SuppressEvents = { FULLSCREEN = "fullscreen", MAXIMIZE = "maximize", ACTIVATE = "activate", ACTIVATE_FOCUS = "activatefocus", FULLSCREEN_OUTPUT = "fullscreenoutput", X11_CONFIG_REQUEST = "x11configrequest", } local function pin() return { pin = true } end local function group() return { group = true } end local function suppress_event(events) events = events or {} return { suppress_event = table.concat(events, " ") } end local ContentType = { NONE = "none", PHOTO = "photo", VIDEO = "video", GAME = "game", } local function content(content) return { content = content } end local function no_close_for(milliseconds) return { no_close_for = milliseconds } end local function scrolling_width(width) return { scrolling_width = width } end -- Dynamic Effects local function no_blur() return { no_blur = true } end local function no_dim() return { no_dim = true } end local function no_focus() return { no_focus = true } end local function stay_focused() return { stay_focused = true } end -- Matching Properties local function matches_class(class) return { class = class } end local function matches_title(title) return { title = title } end local function matches_initial_class(class) return { initial_class = class } end local function matches_initial_title(title) return { initial_title = title } end local function has_tag(tag) return { tag = tag } end local function is_xwayland() return { xwayland = true } end local function is_not_xwayland() return { xwalyand = false } end local function is_float() return { float = true } end local function is_tiling() return { float = false } end local function is_fullscreen() return { fullscreen = true } end local function is_not_fullscreen() return { fullscreen = false } end local function is_pinned() return { pin = true } end local function is_not_pinned() return { pin = false } end local function has_focus() return { focus = true } end local function has_no_focus() return { focus = false } end local function is_grouped() return { group = true } end local function is_not_grouped() return { group = false } end local function is_modal() return { modal = true } end local function is_not_modal() return { modal = false } end local function has_fullscreen_state_client(state) return { fullscreen_state_client = state } end local function has_fullscreen_state_internal(state) return { fullscreen_state_internal = state } end local function is_on_workspace(workspace) return { workspace = workspace } end local function has_content(content) return { content = content } end local function has_xdg_tag(tag) return { xdg_tag = tag } end local function dump(t, indent) indent = indent or 0 local prefix = string.rep(" ", indent) if type(t) ~= "table" then print(prefix .. tostring(t)) return end print(prefix .. "{") for k, v in pairs(t) do local key = tostring(k) if type(v) == "table" then print(prefix .. " " .. key .. " = ") dump(v, indent + 1) else print(prefix .. " " .. key .. " = " .. tostring(v)) end end print(prefix .. "}") end local function rule(matches, effects) local flat_matches = {} for _, match in ipairs(matches) do for k, v in pairs(match) do flat_matches[k] = v end end local args = { match = flat_matches } for _, effect in ipairs(effects) do for k,v in pairs(effect) do args[k] = v end end hl.window_rule(args) debug_notify(dump(args)) end -- Ignore maximize requests rule( { matches_class("^.*$") }, { suppress_event({SuppressEvents.MAXIMIZE}) } ) -- Do not dim full screen applications rule( { is_fullscreen() }, { no_dim(), no_blur() } ) -- Do not dim video content rule( { has_content(ContentType.VIDEO) }, { no_dim(), no_blur() } ) -- System Utilities rule( { matches_class("^(org.pulseaudio.pavucontrol)$") }, { float(), center(), size(800, 600) } ) rule( { matches_class("^(nm-connection-editor)$") }, { float(), center(), size(800, 600) } ) rule( { matches_class("^(xdg-desktop-portal)$") }, { float(), center(), size(800, 600) } ) rule( { matches_class("^(org.gnome.seahorse.Application)$") }, { float(), center(), size(800, 600) } ) -- Nemo rule( { matches_class("^(nemo)$") }, { float(), center(), size(1200, 700) } ) -- Librewolf and Firefox rule( { matches_class("^(firefox|librewolf)$"), matches_title("^(Picture-in-Picture)$") }, { float() } ) rule( { matches_class("^(firefox|librewolf)$"), matches_title("^.*(Youtube).*$") }, { content(ContentType.VIDEO), no_dim(), no_blur() } ) -- MPV rule( { matches_class("^(mpv)$") }, { content(ContentType.VIDEO), no_dim(), no_blur() } ) -- Java rule( { matches_class("^(net-sourceforge-jnlp-runtime-Boot)$"), matches_title("^$") }, { float(), center() } ) rule( { matches_class("^$"), matches_title("^(Java)$") }, { float(), center() } ) -- StellwerkSimulator rule( { matches_title("^(StellwerkSim Kommunikator)$") }, { tile() } ) rule( { matches_class("^(java-lang-Thread|net-sourceforge-jnlp-runtime-Boot)$"), matches_title("^(BÜ Zeiten|Elementname|Verspätungsmeldung.*)$") }, { float(), pin() } ) rule( { matches_class("^(java-lang-Thread|net-sourceforge-jnlp-runtime-Boot)$"), matches_title("^(Verspätungsmeldung.*)$") }, { stay_focused() } ) rule( { matches_title("^(.*StellwerkSim.*)$") }, { no_dim(), no_blur() } ) rule( { matches_class("^(java-lang-Thread|net-sourceforge-jnlp-runtime-Boot)$"), matches_title("^(StellwerkSim Funktionstest|Downloading...|Wirklich schlie.*)$") }, { float(), center() } ) -- Qualculate rule( { matches_class("^(qalculate-gtk)$") }, { float(), size(700, 600), center(), pin() } )