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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
diff --git a/plugins/window-rules/view-action-interface.cpp b/plugins/window-rules/view-action-interface.cpp
index eb973280..839c9fb5 100644
--- a/plugins/window-rules/view-action-interface.cpp
+++ b/plugins/window-rules/view-action-interface.cpp
@@ -6,6 +6,7 @@
#include "wayfire/plugins/grid.hpp"
#include "wayfire/util/log.hpp"
#include "wayfire/view-transform.hpp"
+#include <wayfire/signal-definitions.hpp>
#include <algorithm>
#include <cfloat>
@@ -16,7 +17,9 @@
namespace wf
{
view_action_interface_t::~view_action_interface_t()
-{}
+{
+ _view->erase_data("wm-actions-above");
+}
bool view_action_interface_t::execute(const std::string & name,
const std::vector<variant_t> & args)
@@ -173,6 +176,14 @@ bool view_action_interface_t::execute(const std::string & name,
}
return true;
+ } else if (name == "sticky")
+ {
+ _make_sticky();
+ return false;
+ } else if (name == "always_on_top")
+ {
+ _always_on_top();
+ return false;
}
LOGE("View action interface: Unsupported action execution requested. Name: ",
@@ -186,6 +197,11 @@ void view_action_interface_t::set_view(wayfire_view view)
_view = view;
}
+void view_action_interface_t::set_above_layer(nonstd::observer_ptr<wf::sublayer_t> always_above)
+{
+ _always_above = always_above;
+}
+
void view_action_interface_t::_maximize()
{
_view->tile_request(wf::TILED_EDGES_ALL);
@@ -206,6 +222,41 @@ void view_action_interface_t::_unminimize()
_view->set_minimized(false);
}
+void view_action_interface_t::_make_sticky()
+{
+ _view->set_sticky(1);
+}
+
+void view_action_interface_t::_always_on_top()
+{
+ if (!_view)
+ {
+ return;
+ }
+
+ auto output = _view->get_output();
+ if (!output)
+ {
+ return;
+ }
+
+ if (_view->has_data("wm-actions-above"))
+ {
+ output->workspace->add_view(_view,
+ (wf::layer_t)output->workspace->get_view_layer(_view));
+ _view->erase_data("wm-actions-above");
+ } else
+ {
+ output->workspace->add_view_to_sublayer(_view, _always_above);
+ _view->store_data(std::make_unique<wf::custom_data_t>(),
+ "wm-actions-above");
+ }
+
+ wf::_view_signal data;
+ data.view = _view;
+ output->emit_signal("wm-actions-above-changed", &data);
+}
+
std::tuple<bool, float> view_action_interface_t::_expect_float(
const std::vector<variant_t> & args, std::size_t position)
{
diff --git a/plugins/window-rules/view-action-interface.hpp b/plugins/window-rules/view-action-interface.hpp
index 26c34bc7..0f23607d 100644
--- a/plugins/window-rules/view-action-interface.hpp
+++ b/plugins/window-rules/view-action-interface.hpp
@@ -3,6 +3,7 @@
#include "wayfire/action/action_interface.hpp"
#include "wayfire/view.hpp"
+#include <wayfire/workspace-manager.hpp>
#include <string>
#include <tuple>
#include <vector>
@@ -18,12 +19,15 @@ class view_action_interface_t : public action_interface_t
const std::vector<variant_t> & args) override;
void set_view(wayfire_view view);
+ void set_above_layer(nonstd::observer_ptr<wf::sublayer_t> always_above);
private:
void _maximize();
void _unmaximize();
void _minimize();
void _unminimize();
+ void _make_sticky();
+ void _always_on_top();
std::tuple<bool, float> _expect_float(const std::vector<variant_t> & args,
std::size_t position);
@@ -51,6 +55,7 @@ class view_action_interface_t : public action_interface_t
wf::geometry_t _get_workspace_grid_geometry(wf::output_t *output) const;
wayfire_view _view;
+ nonstd::observer_ptr<wf::sublayer_t> _always_above;
};
} // End namespace wf.
diff --git a/plugins/window-rules/window-rules.cpp b/plugins/window-rules/window-rules.cpp
index 295dd798..723b2f16 100644
--- a/plugins/window-rules/window-rules.cpp
+++ b/plugins/window-rules/window-rules.cpp
@@ -26,6 +26,7 @@ class wayfire_window_rules_t : public wf::plugin_interface_t
void apply(const std::string & signal, wf::signal_data_t *data);
private:
+ nonstd::observer_ptr<wf::sublayer_t> always_above;
void setup_rules_from_config();
wf::lexer_t _lexer;
@@ -87,6 +88,9 @@ void wayfire_window_rules_t::init()
output->connect_signal("view-minimized", &_minimized);
output->connect_signal("view-fullscreen", &_fullscreened);
wf::get_core().connect_signal("reload-config", &_reload_config);
+
+ always_above = output->workspace->create_sublayer(
+ wf::LAYER_WORKSPACE, wf::SUBLAYER_DOCKED_ABOVE);
}
void wayfire_window_rules_t::fini()
@@ -96,6 +100,15 @@ void wayfire_window_rules_t::fini()
{
wf::get_core().erase_data<wf::lambda_rules_registrations_t>();
}
+ auto always_on_top_views =
+ output->workspace->get_views_in_sublayer(always_above);
+
+ for (auto view : always_on_top_views)
+ {
+ view->erase_data("wm-actions-above");
+ }
+
+ output->workspace->destroy_sublayer(always_above);
}
void wayfire_window_rules_t::apply(const std::string & signal,
@@ -128,6 +141,7 @@ void wayfire_window_rules_t::apply(const std::string & signal,
{
_access_interface.set_view(view);
_action_interface.set_view(view);
+ _action_interface.set_above_layer(always_above);
auto error = rule->apply(signal, _access_interface, _action_interface);
if (error)
{
@@ -200,10 +214,11 @@ void wayfire_window_rules_t::setup_rules_from_config()
{
_lexer.reset(opt->get_value_str());
auto rule = wf::rule_parser_t().parse(_lexer);
- if (rule != nullptr)
+ if (!rule)
{
- _rules.push_back(rule);
+ continue;
}
+ _rules.push_back(rule);
}
}
|