WayfireWM / WayfireWM/wayfire

Wayfire crashes when alpha value is missing in autogenerated rule

Open
#2,957 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug low-priority PRs-welcome
Dominant language
C++
Stars
3.1k
Forks
237
Avg merge
1h 43m
Merged PRs (30d)
1

Description

Wayfire version

0.11.0-3fba4963 (Jan 16 2026) branch fix-xwayland wlroots-0.19.2

Describe the bug

Wayfire crashes when missing alpha value (0.9) in autogenerated rule on created if !(type is "toplevel") then set alpha

To Reproduce:

  1. Add a rule through ipc with the following contents:
    ['autogenerated4', 'on created if !(type is "toplevel") then set alpha']
    
    
## Screenshots / Videos / Stacktrace
Unhandled exception
    #0 0x7fbafa964865 in __sanitizer_print_stack_trace /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_stack.cpp:87
    #1 0x56305de6e7a9 in wf::print_trace(bool) ../src/debug.cpp:260
    #2 0x56305de2bb57 in operator() ../src/main.cpp:406
    #3 0x56305de2bb6f in _FUN ../src/main.cpp:408
    #4 0x7fbaf98b3c8b in __cxxabiv1::__terminate(void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
    #5 0x7fbaf9894647 in std::terminate() /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
    #6 0x7fbaf98b3f98 in __cxa_throw /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_throw.cc:98
    #7 0x7fbaf989a734 in std::__throw_out_of_range_fmt(char const*, ...) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/functexcept.cc:101
    #8 0x56305dfb845d in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::at(unsigned long) /usr/include/c++/15.2.1/bits/basic_string.h:1412
    #9 0x7fbafa472ac4 in wf::lexer_t::parse_symbol() ../subprojects/wf-utils/wayfire/lexer/lexer.cpp:61
    #10 0x7fbafa4977ce in wf::action_parser_t::parse(wf::lexer_t&) ../subprojects/wf-utils/wayfire/parser/action_parser.cpp:26
    #11 0x7fbafa4c247a in wf::rule_parser_t::parse(wf::lexer_t&) ../subprojects/wf-utils/wayfire/parser/rule_parser.cpp:79
    #12 0x7bbad7f3a4c4 in wayfire_window_rules_t::setup_rules_from_config() ../plugins/window-rules/window-rules.cpp:191
    #13 0x7bbad7f43419 in wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}::operator()(wf::reload_config_signal*) const ../plugins/window-rules/window-rules.cpp:61
    #14 0x7bbad7f78960 in void std::__invoke_impl<void, wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}&, wf::reload_config_signal*>(std::__invoke_other, wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}&, wf::reload_config_signal*&&) /usr/include/c++/15.2.1/bits/invoke.h:63
    #15 0x7bbad7f6cee2 in std::enable_if<is_invocable_r_v<void, wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}&, wf::reload_config_signal*>, void>::type std::__invoke_r<void, wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}&, wf::reload_config_signal*>(wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}&, wf::reload_config_signal*&&) /usr/include/c++/15.2.1/bits/invoke.h:113
    #16 0x7bbad7f61228 in std::_Function_handler<void (wf::reload_config_signal*), wayfire_window_rules_t::_reload_config::{lambda(wf::reload_config_signal*)#1}>::_M_invoke(std::_Any_data const&, wf::reload_config_signal*&&) /usr/include/c++/15.2.1/bits/std_function.h:292
    #17 0x7bbaf3d80ecd in std::function<void (wf::reload_config_signal*)>::operator()(wf::reload_config_signal*) const /usr/include/c++/15.2.1/bits/std_function.h:593
    #18 0x7bbaf3d7cf37 in wf::signal::connection_t<wf::reload_config_signal>::emit(wf::reload_config_signal*) ../src/api/wayfire/signal-provider.hpp:104
    #19 0x7bbaf3d771a5 in wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}::operator()(wf::signal::connection_base_t*) const ../src/api/wayfire/signal-provider.hpp:151
    #20 0x7bbaf3d863ba in void std::__invoke_impl<void, wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}&, wf::signal::connection_base_t*>(std::__invoke_other, wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}&, wf::signal::connection_base_t*&&) /usr/include/c++/15.2.1/bits/invoke.h:63
    #21 0x7bbaf3d83e8a in std::enable_if<is_invocable_r_v<void, wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}&, wf::signal::connection_base_t*>, void>::type std::__invoke_r<void, wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}&, wf::signal::connection_base_t*>(wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}&, wf::signal::connection_base_t*&&) /usr/include/c++/15.2.1/bits/invoke.h:113
    #22 0x7bbaf3d8105f in std::_Function_handler<void (wf::signal::connection_base_t*), wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*)::{lambda(wf::signal::connection_base_t*)#1}>::_M_invoke(std::_Any_data const&, wf::signal::connection_base_t*&&) /usr/include/c++/15.2.1/bits/std_function.h:292
    #23 0x56305e034c53 in std::function<void (wf::signal::connection_base_t*)>::operator()(wf::signal::connection_base_t*) const /usr/include/c++/15.2.1/bits/std_function.h:593
    #24 0x56305e02e3b4 in void std::__invoke_impl<void, std::function<void (wf::signal::connection_base_t*)>&, wf::signal::connection_base_t*&>(std::__invoke_other, std::function<void (wf::signal::connection_base_t*)>&, wf::signal::connection_base_t*&) /usr/include/c++/15.2.1/bits/invoke.h:63
    #25 0x56305e025539 in std::enable_if<is_invocable_r_v<void, std::function<void (wf::signal::connection_base_t*)>&, wf::signal::connection_base_t*&>, void>::type std::__invoke_r<void, std::function<void (wf::signal::connection_base_t*)>&, wf::signal::connection_base_t*&>(std::function<void (wf::signal::connection_base_t*)>&, wf::signal::connection_base_t*&) /usr/include/c++/15.2.1/bits/invoke.h:113
    #26 0x56305e01de30 in std::_Function_handler<void (wf::signal::connection_base_t*&), std::function<void (wf::signal::connection_base_t*)> >::_M_invoke(std::_Any_data const&, wf::signal::connection_base_t*&) /usr/include/c++/15.2.1/bits/std_function.h:292
    #27 0x56305e01b7b8 in std::function<void (wf::signal::connection_base_t*&)>::operator()(wf::signal::connection_base_t*&) const /usr/include/c++/15.2.1/bits/std_function.h:593
    #28 0x56305e015f6e in wf::safe_list_t<wf::signal::connection_base_t*>::for_each(std::function<void (wf::signal::connection_base_t*&)>) /usr/include/wayfire/nonstd/safe-list.hpp:73
    #29 0x56305e00ebbd in wf::signal::provider_t::for_each_connection(std::type_index, std::function<void (wf::signal::connection_base_t*)>) ../src/core/object.cpp:40
    #30 0x7bbaf3d77395 in void wf::signal::provider_t::emit<wf::reload_config_signal>(wf::reload_config_signal*) ../src/api/wayfire/signal-provider.hpp:147
    #31 0x7bbad8df86f2 in wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}::operator()(wf::json_t const&) const ../plugins/ipc-rules/ipc-utility-methods.hpp:345
    #32 0x7bbad8ef2a6a in wf::json_t std::__invoke_impl<wf::json_t, wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}&, wf::json_t>(std::__invoke_other, wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}&, wf::json_t&&) /usr/include/c++/15.2.1/bits/invoke.h:63
    #33 0x7bbad8ebc704 in std::enable_if<is_invocable_r_v<wf::json_t, wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}&, wf::json_t>, wf::json_t>::type std::__invoke_r<wf::json_t, wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}&, wf::json_t>(wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}&, wf::json_t&&) /usr/include/c++/15.2.1/bits/invoke.h:118
    #34 0x7bbad8e84387 in std::_Function_handler<wf::json_t (wf::json_t), wf::ipc_rules_utility_methods_t::set_config_options::{lambda(wf::json_t const&)#1}>::_M_invoke(std::_Any_data const&, wf::json_t&&) /usr/include/c++/15.2.1/bits/std_function.h:293
    #35 0x7bbad99353be in std::function<wf::json_t (wf::json_t)>::operator()(wf::json_t) const /usr/include/c++/15.2.1/bits/std_function.h:593
    #36 0x7bbad99172d6 in wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}::operator()(wf::json_t const&, wf::ipc::client_interface_t*) const ../plugins/ipc/wayfire/plugins/ipc/ipc-method-repository.hpp:81
    #37 0x7bbad9965583 in wf::json_t std::__invoke_impl<wf::json_t, wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}&, wf::json_t, wf::ipc::client_interface_t*>(std::__invoke_other, wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}&, wf::json_t&&, wf::ipc::client_interface_t*&&) /usr/include/c++/15.2.1/bits/invoke.h:63
    #38 0x7bbad995bff6 in std::enable_if<is_invocable_r_v<wf::json_t, wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}&, wf::json_t, wf::ipc::client_interface_t*>, wf::json_t>::type std::__invoke_r<wf::json_t, wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}&, wf::json_t, wf::ipc::client_interface_t*>(wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}&, wf::json_t&&, wf::ipc::client_interface_t*&&) /usr/include/c++/15.2.1/bits/invoke.h:118
    #39 0x7bbad994e4ea in std::_Function_handler<wf::json_t (wf::json_t, wf::ipc::client_interface_t*), wf::ipc::method_repository_t::register_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<wf::json_t (wf::json_t)>)::{lambda(wf::json_t const&, wf::ipc::client_interface_t*)#1}>::_M_invoke(std::_Any_data const&, wf::json_t&&, wf::ipc::client_interface_t*&&) /usr/include/c++/15.2.1/bits/std_function.h:293
    #40 0x7bbad95966b1 in std::function<wf::json_t (wf::json_t, wf::ipc::client_interface_t*)>::operator()(wf::json_t, wf::ipc::client_interface_t*) const /usr/include/c++/15.2.1/bits/std_function.h:593
    #41 0x7bbad957a9a5 in wf::ipc::method_repository_t::call_method(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, wf::json_t, wf::ipc::client_interface_t*) ../plugins/ipc/wayfire/plugins/ipc/ipc-method-repository.hpp:103
    #42 0x7bbae40c6f67 in wf::ipc::server_t::handle_incoming_message(wf::ipc::client_t*, wf::json_t) ../plugins/ipc/ipc.cpp:137
    #43 0x7bbae40cc2a1 in wf::ipc::client_t::handle_fd_incoming(unsigned int) ../plugins/ipc/ipc.cpp:281
    #44 0x7bbae40c7287 in operator() ../plugins/ipc/ipc.cpp:166
    #45 0x7bbae40d2536 in __invoke_impl<void, wf::ipc::client_t::client_t(wf::ipc::server_t*, int)::<lambda(uint32_t)>&, unsigned int> /usr/include/c++/15.2.1/bits/invoke.h:63
    #46 0x7bbae40d1c2a in __invoke_r<void, wf::ipc::client_t::client_t(wf::ipc::server_t*, int)::<lambda(uint32_t)>&, unsigned int> /usr/include/c++/15.2.1/bits/invoke.h:113
    #47 0x7bbae40d0e78 in _M_invoke /usr/include/c++/15.2.1/bits/std_function.h:292
    #48 0x56305e2a2fa7 in std::function<void (unsigned int)>::operator()(unsigned int) const /usr/include/c++/15.2.1/bits/std_function.h:593
    #49 0x7bbae40c7120 in wl_loop_handle_ipc_client_fd_event(int, unsigned int, void*) ../plugins/ipc/ipc.cpp:144
    #50 0x7fbafafc7641 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa641) (BuildId: eaeed0645478c33a1a975d52ebd375751b26c19e)
    #51 0x7fbafafc9776 in wl_display_run (/usr/lib/libwayland-server.so.0+0xc776) (BuildId: eaeed0645478c33a1a975d52ebd375751b26c19e)
    #52 0x56305de31030 in main ../src/main.cpp:514
    #53 0x7fbaf8c27b8a  (/usr/lib/libc.so.6+0x27b8a) (BuildId: 7ca1c72ce7733770eeca8102591e6d59d18b2e6a)
    #54 0x7fbaf8c27c4a in __libc_start_main (/usr/lib/libc.so.6+0x27c4a) (BuildId: 7ca1c72ce7733770eeca8102591e6d59d18b2e6a)
    #55 0x56305de24c64 in _start (/usr/bin/wayfire+0x1fc6c64) (BuildId: 45c9a97bdc359c85e8e2b493bce92d5f5e346f7f)

Additional context

I didn't read the crash logs and don't know what this is about. I just pasted the output to avoid losing the information.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with subprojects/wf-utils/wayfire/lexer/lexer.cpp and follow parse_symbol() through action_parser.cpp and rule_parser.cpp. Then inspect plugins/window-rules/window-rules.cpp, especially setup_rules_from_config(), and reproduce the IPC rule shown in the issue. Done means the rule with a missing alpha value no longer crashes Wayfire.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.