1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
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();
|