Switcher crash when closing a window
Describe the bug alt tab plugin bad and crashes when a window closes while alt tabbing sometimes it goes to the wrong window when alt tabbing FIX IT ALREADY
To Reproduce Steps to reproduce the behavior:
- Enable plugin X
- Do Y
- Z happens
Expected behavior A clear and concise description of what you expected to happen.
Screenshots or stacktrace If applicable, add screenshots to help explain your problem. If it is a crash, attach the backtrace (or the whole log file), Wayfire will print it in the end of the log file or stdout. Backtrace with address sanitizer enabled (if possible):
Wayfire version 0.5.0, git, package, something else?
'FIX IT ALREADY' isn't helpful. There are many bugs, and time is limited. If you want the project to move forward faster, fix the bug and send a PR.
Also, you have not provided a stacktrace as requested in the template.
Hi, I can reproduce this, and get the following stacktrace:
Thread 1 "wayfire" received signal SIGSEGV, Segmentation fault.
0x0000555555852d0a in wf::output_t::get_relative_geometry (this=0x0) at ../src/output/output.cpp:157
157 auto size = get_screen_size();
(gdb) bt
#0 0x0000555555852d0a in wf::output_t::get_relative_geometry() const (this=0x0) at ../src/output/output.cpp:157
#1 0x000055555584747b in wf::view_3D::calculate_total_transform() (this=0x55555641e490) at ../src/view/view-3d.cpp:201
#2 0x0000555555847753 in wf::view_3D::transform_point(wlr_box, wf::pointf_t) (this=0x55555641e490, geometry=..., point=...) at ../src/view/view-3d.cpp:214
#3 0x0000555555845d63 in wf::view_transformer_t::get_bounding_box(wlr_box, wlr_box) (this=0x55555641e490, view=..., region=...) at ../src/view/view-3d.cpp:14
#4 0x0000555555818561 in wf::view_interface_t::<lambda(auto:7&)>::operator()<std::shared_ptr<wf::view_transform_block_t> >(std::shared_ptr<wf::view_transform_block_t> &) const
(__closure=0x5555565b5db0, tr=std::shared_ptr<wf::view_transform_block_t> (use count 1, weak count 0) = {...}) at ../src/view/view.cpp:973
#5 0x000055555581b400 in std::_Function_handler<void(std::shared_ptr<wf::view_transform_block_t>&), wf::view_interface_t::transform_region(const wlr_box&, nonstd::observer_ptr<wf::view_transformer_t>)::<lambda(auto:7&)> >::_M_invoke(const std::_Any_data &, std::shared_ptr<wf::view_transform_block_t> &)
(__functor=..., __args#0=std::shared_ptr<wf::view_transform_block_t> (use count 1, weak count 0) = {...}) at /usr/include/c++/9/bits/std_function.h:300
#6 0x000055555581f92b in std::function<void (std::shared_ptr<wf::view_transform_block_t>&)>::operator()(std::shared_ptr<wf::view_transform_block_t>&) const
(this=0x7fffffffd5a0, __args#0=std::shared_ptr<wf::view_transform_block_t> (use count 1, weak count 0) = {...}) at /usr/include/c++/9/bits/std_function.h:688
#7 0x000055555581dc2e in wf::safe_list_t<std::shared_ptr<wf::view_transform_block_t> >::for_each(std::function<void (std::shared_ptr<wf::view_transform_block_t>&)>) const
(this=0x5555565b4060, func=...) at ../src/api/wayfire/nonstd/safe-list.hpp:203
#8 0x00005555558186ae in wf::view_interface_t::transform_region(wlr_box const&, nonstd::observer_ptr<wf::view_transformer_t>) (this=0x5555565ba8c8, region=..., upto=...)
at ../src/view/view.cpp:964
#9 0x0000555555818807 in wf::view_interface_t::transform_region(wlr_box const&) (this=0x5555565ba8c8, region=...) at ../src/view/view.cpp:989
#10 0x000055555581743b in wf::view_interface_t::damage() (this=0x5555565ba8c8) at ../src/view/view.cpp:764
#11 0x00005555558175d9 in wf::view_interface_t::set_decoration(std::unique_ptr<wf::decorator_frame_t_t, std::default_delete<wf::decorator_frame_t_t> >)
(this=0x5555565ba8c8, frame=std::unique_ptr<wf::decorator_frame_t_t> = {...}) at ../src/view/view.cpp:792
#12 0x000055555581a171 in wf::view_interface_t::deinitialize() (this=0x5555565ba8c8) at ../src/view/view.cpp:1269
#13 0x00005555557a644c in wf::compositor_core_impl_t::erase_view(nonstd::observer_ptr<wf::view_interface_t>) (this=0x5555559406c0 <wf::compositor_core_impl_t::get()::instance>, v=...)
at ../src/core/core.cpp:757
#14 0x000055555581a69d in wf::view_interface_t::destruct() (this=0x5555565ba8c8) at ../src/view/view.cpp:1335
#15 0x000055555581a066 in wf::view_interface_t::unref() (this=0x5555565ba8c8) at ../src/view/view.cpp:1254
#16 0x0000555555826c3f in wf::wlr_view_t::destroy() (this=0x5555565ba7d0) at ../src/view/view-impl.cpp:400
#17 0x000055555582c1cd in wayfire_xdg_view::destroy() (this=0x5555565ba7d0) at ../src/view/xdg-shell.cpp:461
#18 0x000055555582a72f in wayfire_xdg_view::<lambda(void*)>::operator()(void *) const (__closure=0x5555565bab60) at ../src/view/xdg-shell.cpp:209
#19 0x000055555582e2d5 in std::_Function_handler<void(void*), wayfire_xdg_view::initialize()::<lambda(void*)> >::_M_invoke(const std::_Any_data &, void *&&)
(__functor=..., __args#0=@0x7fffffffd8c0: 0x5555565c2a80) at /usr/include/c++/9/bits/std_function.h:300
#20 0x0000555555761cb5 in std::function<void (void*)>::operator()(void*) const (this=0x5555565bab60, __args#0=0x5555565c2a80) at /usr/include/c++/9/bits/std_function.h:688
#21 0x00005555557615a9 in wf::wl_listener_wrapper::emit(void*) (this=0x5555565bab60, data=0x5555565c2a80) at ../src/util.cpp:526
#22 0x00005555557612a2 in handle_wrapped_listener(wl_listener*, void*) (listener=0x5555565bab80, data=0x5555565c2a80) at ../src/util.cpp:448
#23 0x00007ffff7ebd8cc in wlr_signal_emit_safe () at /usr/local/lib/x86_64-linux-gnu/libwlroots.so.10
#24 0x00007ffff7e93d38 in reset_xdg_surface () at /usr/local/lib/x86_64-linux-gnu/libwlroots.so.10
#25 0x00007ffff7e93dfd in destroy_xdg_surface () at /usr/local/lib/x86_64-linux-gnu/libwlroots.so.10
#26 0x00007ffff7ebd8cc in wlr_signal_emit_safe () at /usr/local/lib/x86_64-linux-gnu/libwlroots.so.10
#27 0x00007ffff7eb1a11 in surface_handle_resource_destroy () at /usr/local/lib/x86_64-linux-gnu/libwlroots.so.10
#28 0x00007ffff7f1120f in destroy_resource () at /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
#29 0x00007ffff7f19191 in wl_map_for_each () at /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
#30 0x00007ffff7f11dc9 in wl_client_destroy () at /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
#31 0x00007ffff7f11ea7 in wl_client_connection_data () at /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
#32 0x00007ffff7f152f2 in wl_event_loop_dispatch () at /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
#33 0x00007ffff7f127e5 in wl_display_run () at /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
#34 0x000055555575d032 in main(int, char**) (argc=3, argv=0x7fffffffe0f8) at ../src/main.cpp:296
The problem seems to be that the 3D view transformer needs an output to be present (in calculate_total_transform()), but output is set to nullptr in wf::compositor_core_impl_t::erase_view() here (frame #13 above).
I think this should happen for all cases when a 3D transformer is still attached while a view is being destroyed. I assume other plugins take care to remove the transformer in time.
Some ideas on how to fix this:
- Maybe
view::damage()should be a no-op if the view is not mapped and / or has no output? As a side note, maybeset_decoration(nullptr)shuld also be a no-op if the current decoration is already unset (i.e.view_impl->frame == nullptr)? - Alternatively, the transformers could be removed earlier in the view deinit sequence?
@dkondor Views and their transformers should work even without an output.
I just looked at the 3D transformer, we use the output for a purpose it shouldn't really be used for .. IIRC the code for scaling depth was just a workaround, which hasn't been properly fixed even up to date. If you have an idea how to drop the dependency on the output, I'm all for it (EDIT: this might require changes to how the other matrices are set up but that's fine by me, if we can make all of it to work, including input redirection)
I see, this makes sense. Unfortunately, I don't fully understand the role of depth_scale, so I'm not sure if I can actually help with this (although, my intuition is that the size of the output should matter to be able to set up the correct perspective, and this is the point where it is taken into account).
I see, this makes sense. Unfortunately, I don't fully understand the role of
depth_scale, so I'm not sure if I can actually help with this (although, my intuition is that the size of the output should matter to be able to set up the correct perspective, and this is the point where it is taken into account).
Yes, the depth scale is just so that the Z coordinates don't blow up and go beyond the clipping planes. But maybe the clipping planes or the view matrix can be set up differently?
sometimes it goes to the wrong window when alt tabbing one window back/left
I looked into changing the other matrices (view_proj), but I couldn't get it to work any better; essentially anything change there messes up the transform_point() function (which is used for calculating the view's position). Maybe a workaround could be to just check if the view does not have an output and use some sensible default value there? (I'm assuming that if a view is not on an output, it will not be visible and this doesn't really matter)