diff --git a/plugins/cube/cube-background.hpp b/plugins/cube/cube-background.hpp index c6e3f48..500be89 100644 --- a/plugins/cube/cube-background.hpp +++ b/plugins/cube/cube-background.hpp @@ -9,6 +9,14 @@ class wf_cube_background_base public: virtual void render_frame(const wf::render_target_t& fb, wf_cube_animation_attribs& attribs) = 0; + // Backgrounds without a camera-independent pose ignore follow_cube. + virtual void render_frame(const wf::render_target_t& fb, + wf_cube_animation_attribs& attribs, bool follow_cube) + { + (void)follow_cube; + render_frame(fb, attribs); + } + virtual ~wf_cube_background_base() = default; }; diff --git a/plugins/cube/cube.cpp b/plugins/cube/cube.cpp index 3b4b857..ce9614b 100644 --- a/plugins/cube/cube.cpp +++ b/plugins/cube/cube.cpp @@ -1316,7 +1316,12 @@ class wayfire_cube : public wf::per_output_plugin_instance_t, public wf::pointer return; } - wf::scene::remove_child(render_node); + // A render pause may already have removed the node. + if (render_node) + { + wf::scene::remove_child(render_node); + } + output->render->damage_whole(); render_node = nullptr; @@ -1712,6 +1717,29 @@ class wayfire_cube : public wf::per_output_plugin_instance_t, public wf::pointer { hyperspace_background->render(data.target, data.damage, wf::dimensions(output->get_relative_geometry()), opacity); + } else if (opacity > 0 && background && (std::string(background_mode) == "skydome" || + std::string(background_mode) == "cubemap")) + { + // The textures are opaque, so fade them with a constant alpha. + GL_CALL(glDisable(GL_DEPTH_TEST)); + GL_CALL(glDisable(GL_CULL_FACE)); + if (opacity < 1.0f) + { + GL_CALL(glEnable(GL_BLEND)); + GL_CALL(glBlendColor(0, 0, 0, opacity)); + GL_CALL(glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA)); + } else + { + GL_CALL(glDisable(GL_BLEND)); + } + + // At rest the pose is identity and both modes agree; while + // moving, follow the cube's yaw and pitch as upstream does. + wf::gles::for_each_scissor_rect(data.target, data.damage, [&] + { + background->render_frame(data.target, animation, !resting_renderer); + }); + GL_CALL(glDisable(GL_BLEND)); } else if (opacity > 0) { // None clears the owned pixels even when the image opacity @@ -1981,12 +2009,28 @@ class wayfire_cube : public wf::per_output_plugin_instance_t, public wf::pointer { shutting_down = true; background_timer.disconnect(); - clear_post_move_window_dim(); if (output->is_plugin_active(grab_interface.name)) { deactivate(); } + + // deactivate() keeps the carried window hidden and dimmed while the + // modifiers are held, but the listeners that release it die with this + // instance. Restore it and drop every node of ours from the scene. + clear_fixed_workspace_overlay(false); + clear_post_move_window_dim(); remove_rest_renderer(); + if (render_node) + { + wf::scene::remove_child(render_node); + render_node = nullptr; + } + + if (fixed_top_node) + { + wf::scene::remove_child(fixed_top_node); + fixed_top_node = nullptr; + } wf::gles::run_in_context_if_gles([&] { diff --git a/plugins/cube/cubemap.hpp b/plugins/cube/cubemap.hpp index e68c8e1..6360612 100644 --- a/plugins/cube/cubemap.hpp +++ b/plugins/cube/cubemap.hpp @@ -9,12 +9,12 @@ class wf_cube_background_cubemap : public wf_cube_background_base wf_cube_background_cubemap(); virtual void render_frame(const wf::render_target_t& fb, wf_cube_animation_attribs& attribs) override; + void render_frame(const wf::render_target_t& fb, + wf_cube_animation_attribs& attribs, bool follow_cube) override; ~wf_cube_background_cubemap(); private: - void render_frame(const wf::render_target_t& fb, - wf_cube_animation_attribs& attribs, bool follow_cube); void reload_texture(); void create_program(); diff --git a/plugins/cube/simple-background.hpp b/plugins/cube/simple-background.hpp index 470aadf..7769269 100644 --- a/plugins/cube/simple-background.hpp +++ b/plugins/cube/simple-background.hpp @@ -9,6 +9,7 @@ class wf_cube_simple_background : public wf_cube_background_base public: wf_cube_simple_background(); + using wf_cube_background_base::render_frame; virtual void render_frame(const wf::render_target_t& fb, wf_cube_animation_attribs& attribs) override; }; diff --git a/plugins/cube/skydome.hpp b/plugins/cube/skydome.hpp index a64bce9..9df12d0 100644 --- a/plugins/cube/skydome.hpp +++ b/plugins/cube/skydome.hpp @@ -11,14 +11,14 @@ class wf_cube_background_skydome : public wf_cube_background_base wf_cube_background_skydome(wf::output_t *output); virtual void render_frame(const wf::render_target_t& fb, wf_cube_animation_attribs& attribs) override; + void render_frame(const wf::render_target_t& fb, + wf_cube_animation_attribs& attribs, bool follow_cube) override; virtual ~wf_cube_background_skydome(); private: wf::output_t *output; - void render_frame(const wf::render_target_t& fb, - wf_cube_animation_attribs& attribs, bool follow_cube); void load_program(); void fill_vertices(); void reload_texture();