Skip to content

Instantly share code, notes, and snippets.

@kode54
Created August 29, 2024 05:09
Show Gist options
  • Save kode54/58b9e30ed73f82e1cfb040fe84f36c66 to your computer and use it in GitHub Desktop.
Save kode54/58b9e30ed73f82e1cfb040fe84f36c66 to your computer and use it in GitHub Desktop.
Wayfire display recovery attempt; for track-wlroots 0.18 branch
diff --git a/src/core/core-impl.hpp b/src/core/core-impl.hpp
index 8c31dfe6..1b4a6212 100644
--- a/src/core/core-impl.hpp
+++ b/src/core/core-impl.hpp
@@ -38,6 +38,8 @@ class compositor_core_impl_t : public compositor_core_t
void disconnect_signals();
void fini();
+ void reconfigure_outputs();
+
static compositor_core_impl_t& get();
static compositor_core_impl_t& allocate_core();
static void deallocate_core();
diff --git a/src/core/core.cpp b/src/core/core.cpp
index fa35b895..b9dbb052 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -229,6 +229,19 @@ void wf::compositor_core_impl_t::post_init()
this->emit(&startup_ev);
}
+void wf::compositor_core_impl_t::reconfigure_outputs()
+{
+ output_layout = std::make_unique<wf::output_layout_t>(backend);
+ protocols.output_manager->layout = output_layout->get_handle();
+
+ // Move pointer to the middle of the leftmost, topmost output
+ wf::pointf_t p;
+ wf::output_t *wo = wf::get_core().output_layout->get_output_coords_at({FLT_MIN, FLT_MIN}, p);
+ // Output might be noop but guaranteed to not be null
+ wo->ensure_pointer(true);
+ seat->focus_output(wo);
+}
+
void wf::compositor_core_impl_t::shutdown()
{
// We might get multiple signals in some scenarios. Shutdown only on the first instance.
diff --git a/src/main.cpp b/src/main.cpp
index 7cb23e1d..bbb6c5f9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -401,6 +401,67 @@ int main(int argc, char *argv[])
core.egl = wlr_gles2_renderer_get_egl(core.renderer);
assert(core.egl);
+ wf::wl_listener_wrapper on_renderer_lost;
+ on_renderer_lost.set_callback([&] (void *data)
+ {
+ drm_fd = wlr_backend_get_drm_fd(core.backend);
+ if (drm_fd < 0)
+ {
+ char *drm_device = getenv("WLR_RENDER_DRM_DEVICE");
+ if (drm_device)
+ {
+ drm_fd = open(drm_device, O_RDWR | O_CLOEXEC);
+ }
+
+ if (drm_fd < 0)
+ {
+ LOGE("Failed to get DRM file descriptor,",
+ " try specifying a valid WLR_RENDER_DRM_DEVICE!");
+ wl_display_destroy_clients(core.display);
+ wl_display_destroy(core.display);
+ return;
+ }
+ }
+
+ struct wlr_renderer *renderer = wlr_gles2_renderer_create_with_drm_fd(drm_fd);
+ if (!renderer)
+ {
+ LOGE("Failed to create new renderer");
+ return;
+ }
+ struct wlr_allocator *allocator = wlr_allocator_autocreate(core.backend, renderer);
+ if (!allocator)
+ {
+ LOGE("Failed to create new allocator");
+ return;
+ }
+ struct wlr_egl *egl = wlr_gles2_renderer_get_egl(renderer);
+ if (!egl)
+ {
+ LOGE("Failed to get new EGL");
+ return;
+ }
+
+ struct wlr_renderer *old_renderer = core.renderer;
+ struct wlr_allocator *old_allocator = core.allocator;
+ struct wlr_egl *old_egl = core.egl;
+
+ core.renderer = renderer;
+ core.allocator = allocator;
+ core.egl = egl;
+
+ on_renderer_lost.disconnect();
+ on_renderer_lost.connect(&renderer->events.lost);
+
+ wlr_compositor_set_renderer(core.compositor, renderer);
+
+ core.reconfigure_outputs();
+
+ wlr_allocator_destroy(old_allocator);
+ wlr_renderer_destroy(old_renderer);
+ });
+ on_renderer_lost.connect(&core.renderer->events.lost);
+
if (!drop_permissions())
{
wl_display_destroy_clients(core.display);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment