summaryrefslogtreecommitdiff
path: root/gui-wm/wayfire/files/wayfire-0.11.0-workspace-backgrounds.patch
blob: 4e51565bdafcab8c1f7fa1dc4fae73881c33f54f (plain)
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
--- a/src/api/wayfire/workspace-stream.hpp
+++ b/src/api/wayfire/workspace-stream.hpp
@@ -8,6 +8,27 @@
 
 namespace wf
 {
+/** An output-local wallpaper which can render a specific workspace.
+ *
+ * Attach directly to an output's BOTTOM layer, behind its other children.
+ * Normal scene rendering selects the active workspace. Workspace streams call
+ * gen_workspace_instances with their own coordinates, without translating the
+ * wallpaper like a window or duplicating its normal render instance.
+ */
+class workspace_background_node_t : public scene::node_t
+{
+  public:
+    workspace_background_node_t() : scene::node_t(false)
+    {}
+    virtual void gen_workspace_instances(wf::point_t workspace,
+        std::vector<scene::render_instance_uptr>& instances,
+        scene::damage_callback push_damage, wf::output_t *output) = 0;
+};
+
+// Additive API capability; referencing this symbol prevents plugins using the
+// new stream contract from silently loading on a compositor without it.
+uint32_t workspace_background_api_version();
+
 /**
  * A workspace stream is a special node which displays a workspace of an output.
  */
--- a/src/output/workspace-stream.cpp
+++ b/src/output/workspace-stream.cpp
@@ -12,14 +12,19 @@
 
 namespace wf
 {
+uint32_t workspace_background_api_version()
+{
+    return 1;
+}
+
 class workspace_stream_node_t::workspace_stream_instance_t : public scene::
     render_instance_t
 {
     workspace_stream_node_t *self;
 
     std::vector<scene::render_instance_uptr> instances;
-    // True for each instance generated from a desktop environment view.
-    std::vector<bool> is_desktop_environment;
+    // True for output-local instances (desktop surfaces and workspace wallpaper).
+    std::vector<bool> output_local_instances;
 
     wf::pointf_t get_offset()
     {
@@ -62,6 +67,20 @@
             {
                 if (ch->is_enabled())
                 {
+                    if (auto wallpaper = dynamic_cast<workspace_background_node_t*>(ch.get()))
+                    {
+                        if (self->include_workspace_views)
+                        {
+                            size_t count = this->instances.size();
+                            wallpaper->gen_workspace_instances(self->ws, this->instances,
+                                push_damage, self->output);
+                            output_local_instances.insert(output_local_instances.end(),
+                                this->instances.size() - count, true);
+                        }
+
+                        continue;
+                    }
+
                     auto view = node_to_view(ch);
                     const bool is_de     = (view && (view->role == wf::VIEW_ROLE_DESKTOP_ENVIRONMENT));
                     static wf::option_wrapper_t<std::string> rotate_layer_shell{
@@ -99,18 +118,18 @@
                     ch->gen_render_instances(this->instances,
                         is_de ? push_damage : translate_and_push_damage, self->output);
 
-                    // Mark whether the instances were generated from a desktop environment view
+                    // Mark whether instances use output-local rather than workspace coordinates
                     num_generated = this->instances.size() - num_generated;
                     for (size_t i = 0; i < num_generated; i++)
                     {
                         // Inclusion in a rotating texture does not make a panel
                         // workspace-local: keep it visible and damaged on every face.
-                        is_desktop_environment.push_back(is_de);
+                        output_local_instances.push_back(is_de);
                     }
                 }
             }
 
-            wf::dassert(instances.size() == is_desktop_environment.size(), "Setting de flag is wrong!");
+            wf::dassert(instances.size() == output_local_instances.size(), "Setting de flag is wrong!");
         }
     }
 
@@ -128,7 +147,7 @@
             our_damage += offset;
             for (size_t i = 0; i < instances.size(); i++)
             {
-                if (is_desktop_environment[i])
+                if (output_local_instances[i])
                 {
                     // Special handling: move everything to 'current workspace' so that panels and backgrounds
                     // render at the correct position.
--- a/plugins/cube/cube.cpp
+++ b/plugins/cube/cube.cpp
@@ -1132,7 +1132,10 @@
              * that are on the back, and then we render those at the front, so we
              * don't have to use depth testing and we also can support alpha cube. */
             GL_CALL(glEnable(GL_BLEND));
-            GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
+            // Workspace buffers are composed by wlroots with premultiplied
+            // alpha. Multiplying their RGB by alpha again darkens transparent
+            // wallpapers and windows when the face is blended onto the desktop.
+            GL_CALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
             GL_CALL(glEnable(GL_CULL_FACE));
             wf::gles::for_each_scissor_rect(data.target, data.damage, [&]
             {