├── meson_options.txt
├── SECURITY.md
├── compile-schemas.sh
├── dbus_interface.xml
├── org.wayland.compositor.dbus.gschema.xml
├── LICENSE
├── README.md
├── meson.build
├── wf-prop
├── dbus_scale_filter.hpp
├── wf-prop.cpp
├── dbus_interface.cpp
├── uncrustify.ini
└── dbus_interface_backend.cpp
/meson_options.txt:
--------------------------------------------------------------------------------
1 | option('build_wf_prop', type : 'boolean', value : true)
2 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 | Only master branch get's security attention
3 |
4 | ## Reporting a Vulnerability
5 | send an email to admin@novoslinux.com
6 |
--------------------------------------------------------------------------------
/compile-schemas.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Only compile schemas if DESTDIR isn't set
4 | [ ! -z "$DESTDIR" ] && exit 0
5 |
6 | exec glib-compile-schemas "$MESON_INSTALL_DESTDIR_PREFIX/$1"
7 |
--------------------------------------------------------------------------------
/dbus_interface.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <_short>DBus Interface
5 | <_long>DBus Interface @ org.wayland.compositor
6 | Desktop
7 |
8 |
9 |
--------------------------------------------------------------------------------
/org.wayland.compositor.dbus.gschema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 | geometry-signal
7 | geometry-signal
8 |
9 |
10 | ""
11 | Command that runs on session startup
12 | Command that runs on session startup
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Damian Ivanov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DBus Wayfire plugin
2 |
3 | Authors: Damian Ivanov
4 |
5 | Contributors: https://github.com/damianatorrpm/wayfire-plugin_dbus_interface/graphs/contributors
6 |
7 | ### Installation
8 | - Install (wayfire-plugins-extra)[https://github.com/WayfireWM/wayfire-plugins-extra]
9 | - Build & install the plugin and wf-prop: `meson build && ninja -C build && sudo meson install -C build`
10 | - Enable `glib-main-loop` and `dbus_interface` in your wayfire.ini
11 |
12 | If one of the plugins isn't loaded (check wayfire's debug output), make sure the plugin was installed to the correct path.
13 |
14 | ### Coding style
15 | * uncrustify.ini in the repo
16 | * follow the style used
17 | * using 'auto' is strongly discouraged
18 |
19 | ### wf-prop
20 | * wf-prop l / wf-prop list for a detailed list of all taskmanger relevant (toplevel) windows.
21 | * wf-prop + click on a window to query details about that window
22 |
23 | ### other examples
24 |
25 | * To continuously monitor for signals
26 | >gdbus monitor --session --dest org.wayland.compositor --object-path /org/wayland/compositor"
27 |
28 | * To query taskamanager relevant windows
29 | >gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_vector_taskman_ids
30 |
31 | * To fullscreen a window (query the id you want from the properties)
32 | >gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.fullscreen_view $id 1
33 |
34 | * To restore previous state from fullscreen
35 | >gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.fullscreen_view $id 0
36 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | project(
2 | 'wayfire-plugin-dbus_interface',
3 | 'c',
4 | 'cpp',
5 | version: '0.3',
6 | license: 'MIT',
7 | meson_version: '>=0.51.0',
8 | default_options: [
9 | 'cpp_std=c++17',
10 | 'c_std=c17',
11 | 'werror=false',
12 | ],
13 | )
14 |
15 | gio = dependency('gio-2.0')
16 | giomm = dependency('giomm-2.4', required : get_option('build_wf_prop'))
17 |
18 | wayfire = dependency('wayfire', required : true)
19 | wlroots = dependency('wlroots')
20 | wfconfig = dependency('wf-config')
21 | glib = dependency('glib-2.0')
22 | xcb = dependency('xcb')
23 | xcbres = dependency('xcb-res')
24 |
25 | add_project_arguments(['-DWLR_USE_UNSTABLE'], language: ['cpp', 'c'])
26 | add_project_arguments(['-DWAYFIRE_PLUGIN'], language: ['cpp', 'c'])
27 | add_project_arguments(['-Wno-unused-parameter'], language: 'cpp')
28 | add_project_link_arguments(['-rdynamic'], language:'cpp')
29 |
30 |
31 |
32 | ######################### Finish ###########################
33 | schemas_dir = 'share/glib-2.0/schemas'
34 | install_data('org.wayland.compositor.dbus.gschema.xml',
35 | install_dir: join_paths(get_option('prefix'), schemas_dir))
36 | meson.add_install_script('compile-schemas.sh', schemas_dir)
37 |
38 | pms = shared_module('dbus_interface', 'dbus_interface.cpp',
39 | dependencies: [wayfire, wlroots, gio, xcb, xcbres],
40 | install: true, install_dir: wayfire.get_variable(pkgconfig: 'plugindir'),
41 | cpp_args : ['-Wno-write-strings', '-Wno-unused-parameter', '-Wno-format-security'])
42 | install_data('dbus_interface.xml', install_dir: wayfire.get_variable(pkgconfig: 'metadatadir'))
43 |
44 | if get_option('build_wf_prop')
45 | executable('wf-prop', 'wf-prop.cpp',
46 | dependencies: [gio, giomm],
47 | install: true,
48 | )
49 | endif
50 |
51 | summary = [
52 | '',
53 | '----------------',
54 | 'wayfire-plugins-dbus_interface @0@'.format(meson.project_version()),
55 | 'build wf-prop: @0@'.format(get_option('build_wf_prop')),
56 | '----------------',
57 | ''
58 | ]
59 | message('\n'.join(summary))
60 |
--------------------------------------------------------------------------------
/wf-prop:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | busctl --user call org.wayland.compositor /org/wayland/compositor org.wayland.compositor enable_property_mode b true
4 | ( gdbus monitor --session --dest org.wayland.compositor --object-path /org/wayland/compositor & echo $! >&3 ) 3>gdbus_pid |
5 |
6 | while read -r line; do
7 | if [[ $line == *"/org/wayland/compositor: org.wayland.compositor.view_pressed (uint32"* ]]; then
8 | busctl --user call org.wayland.compositor /org/wayland/compositor org.wayland.compositor enable_property_mode b false
9 | VIEW_ID=$(echo $line| cut -d'2' -f 2)
10 | VIEW_ID="${VIEW_ID%,*}"
11 | printf "\n\n"
12 | echo app id: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_app_id 0)
13 | echo title: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_title 0)
14 | echo PID/UID/GID: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_credentials 0)
15 | echo active: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_active 0)
16 | echo minimized: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_minimized 0)
17 | echo maximized: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_maximized 0)
18 | echo fullscreen: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_fullscreen 0)
19 | echo above: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_above 0)
20 | echo workspaces: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_workspaces 0)
21 | echo role: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_role 0)
22 | echo ****XWayland Information - no data means this native wayland window***
23 | # Extend with properties you like
24 | # query_view_xwayland_atom_string for string
25 | # query_view_xwayland_atom_cardinal for int
26 | echo WID: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_xwayland_wid 0)
27 | echo _NET_WM_NAME: $(gdbus call --session --dest org.wayland.compositor --object-path /org/wayland/compositor --method org.wayland.compositor.query_view_xwayland_atom_string 0 _NET_WM_NAME)
28 | kill $(
4 | *
5 | * dbus_scale_filter.hpp -- helper class to filter scaled apps by dbus
6 | *********************************************************************/
7 |
8 | #ifndef DBUS_SCALE_FILTER_HPP
9 | #define DBUS_SCALE_FILTER_HPP
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | /* one instance of each of this class is added to each output */
18 | class dbus_scale_filter : public wf::custom_data_t
19 | {
20 | protected:
21 | std::string filter;
22 |
23 | static unsigned char
24 | transform (unsigned char c)
25 | {
26 | if (std::isspace(c))
27 | {
28 | return ' ';
29 | }
30 |
31 | return (c <= 127) ? (unsigned char)std::tolower(c) : c;
32 | }
33 |
34 | bool
35 | should_show_view (wayfire_view v)
36 | {
37 | if (filter.empty())
38 | {
39 | return true;
40 | }
41 |
42 | std::string app_id = v->get_app_id();
43 | std::transform(app_id.begin(), app_id.end(), app_id.begin(), transform);
44 |
45 | return filter == app_id;
46 | }
47 |
48 | wf::signal_connection_t view_filter{[this] (wf::signal_data_t* data)
49 | {
50 | auto signal = static_cast (data);
51 | scale_filter_views(signal, [this] (wayfire_view v)
52 | {
53 | return !should_show_view(v);
54 | });
55 | }
56 | };
57 |
58 | wf::signal_connection_t scale_end{[this] (auto)
59 | {
60 | filter.clear();
61 | }
62 | };
63 |
64 | void
65 | connect_signals (wf::output_t* output)
66 | {
67 | output->connect_signal("scale-filter", &view_filter);
68 | output->connect_signal("scale-end", &scale_end);
69 | }
70 |
71 | public:
72 | static nonstd::observer_ptr
73 | get (wf::output_t* output)
74 | {
75 | auto ret = output->get_data ();
76 | if (ret)
77 | {
78 | return ret;
79 | }
80 |
81 | dbus_scale_filter* new_ret = new dbus_scale_filter();
82 | output->store_data(std::unique_ptr (new_ret));
83 | new_ret->connect_signals(output);
84 |
85 | return new_ret;
86 | }
87 |
88 | void
89 | set_filter (const std::string& new_filter)
90 | {
91 | filter = new_filter;
92 | std::transform(filter.begin(), filter.end(), filter.begin(), transform);
93 | }
94 |
95 | void
96 | set_filter (std::string&& new_filter)
97 | {
98 | filter = std::move(new_filter);
99 | std::transform(filter.begin(), filter.end(), filter.begin(), transform);
100 | }
101 |
102 | // unload all instances of filters attached to all outputs
103 | static void
104 | unload ()
105 | {
106 | wf::compositor_core_t& core = wf::get_core();
107 | for (auto output : core.output_layout->get_outputs())
108 | {
109 | output->erase_data ();
110 | }
111 | }
112 | };
113 |
114 | #endif
--------------------------------------------------------------------------------
/wf-prop.cpp:
--------------------------------------------------------------------------------
1 | /*******************************************************************
2 | * This file is licensed under the MIT license.
3 | * Copyright (C) 2019 - 2020 Damian Ivanov
4 | ********************************************************************/
5 |
6 | #define DBUS_ID "org.wayland.compositor"
7 | #define DBUS_PATH "/org/wayland/compositor"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | using DBusConnection = Glib::RefPtr;
19 | using DBusProxy = Glib::RefPtr;
20 |
21 | /*
22 | * Print a list of query_view_taskman_ids and output them as
23 | *
24 | */
25 | static gboolean list = FALSE;
26 | static DBusConnection connection;
27 | static DBusProxy proxy;
28 |
29 | static std::vector>
30 | query_view_workspaces (guint view_id)
31 | {
32 | std::vector> workspaces;
33 |
34 | GError* error = NULL;
35 | GVariant* tmp = NULL;
36 | int x, y;
37 |
38 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_workspaces",
39 | g_variant_new("(u)", view_id),
40 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
41 |
42 | g_assert_no_error(error);
43 |
44 | GVariantIter iter;
45 | GVariantIter iter2;
46 | GVariantIter iter3;
47 | GVariant* child;
48 | GVariant* cchild;
49 | GVariant* ccchild;
50 |
51 | g_variant_iter_init(&iter, tmp);
52 |
53 | while ((child = g_variant_iter_next_value(&iter)))
54 | {
55 | g_variant_iter_init(&iter2, child);
56 | while ((cchild = g_variant_iter_next_value(&iter2)))
57 | {
58 | g_variant_get_child(cchild, 0, "i", &x);
59 | g_variant_get_child(cchild, 1, "i", &y);
60 | g_debug("view workspaces: %i %i", x, y);
61 | workspaces.push_back(std::make_pair(x, y));
62 | }
63 | }
64 |
65 | g_variant_unref(tmp);
66 |
67 | if (workspaces.size() == 0) {
68 | g_warning("No workspaces found for view: %u", view_id);
69 | }
70 |
71 | return workspaces;
72 | }
73 |
74 | static uint
75 | query_view_output (guint view_id)
76 | {
77 | GError* error = NULL;
78 | GVariant* tmp = NULL;
79 | uint value = 0;
80 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_output",
81 | g_variant_new("(u)", view_id),
82 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
83 | g_assert_no_error(error);
84 | g_variant_get(tmp, "(u)", &value);
85 | g_variant_unref(tmp);
86 |
87 | return value;
88 | }
89 |
90 | static int
91 | query_view_below_view (guint view_id)
92 | {
93 | GVariant* tmp = NULL;
94 | int value = 0;
95 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_below_view",
96 | g_variant_new("(u)", view_id),
97 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
98 | g_variant_get(tmp, "(i)", &value);
99 | g_variant_unref(tmp);
100 |
101 | return value;
102 | }
103 |
104 | static int
105 | query_view_above_view (guint view_id)
106 | {
107 | GVariant* tmp = NULL;
108 | int value = 0;
109 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_above_view",
110 | g_variant_new("(u)", view_id),
111 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
112 | g_variant_get(tmp, "(i)", &value);
113 | g_variant_unref(tmp);
114 |
115 | return value;
116 | }
117 |
118 | static gboolean
119 | query_view_minimized (guint view_id)
120 | {
121 | GError* error = NULL;
122 | GVariant* tmp = NULL;
123 | gboolean value;
124 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_minimized",
125 | g_variant_new("(u)", view_id),
126 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
127 |
128 | g_assert_no_error(error);
129 | g_variant_get(tmp, "(b)", &value);
130 | g_variant_unref(tmp);
131 |
132 | return value;
133 | }
134 |
135 | static gboolean
136 | query_view_maximized (guint view_id)
137 | {
138 | GError* error = NULL;
139 | GVariant* tmp = NULL;
140 | gboolean value;
141 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_maximized",
142 | g_variant_new("(u)", view_id),
143 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
144 |
145 | g_assert_no_error(error);
146 | g_variant_get(tmp, "(b)", &value);
147 | g_variant_unref(tmp);
148 |
149 | return value;
150 | }
151 |
152 | static gboolean
153 | query_view_fullscreen (guint view_id)
154 | {
155 | GError* error = NULL;
156 | GVariant* tmp = NULL;
157 | gboolean value;
158 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_fullscreen",
159 | g_variant_new("(u)", view_id),
160 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
161 |
162 | g_assert_no_error(error);
163 | g_variant_get(tmp, "(b)", &value);
164 | g_variant_unref(tmp);
165 |
166 | return value;
167 | }
168 |
169 | static gchar*
170 | query_output_name (guint output_id)
171 | {
172 | GError* error = NULL;
173 | GVariant* tmp = NULL;
174 | gchar* value = NULL;
175 |
176 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_output_name",
177 | g_variant_new("(u)", output_id),
178 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
179 | g_assert_no_error(error);
180 | g_variant_get(tmp, "(s)", &value);
181 | g_variant_unref(tmp);
182 |
183 | return value;
184 | }
185 |
186 | static std::pair
187 | query_output_workspace (guint output_id)
188 | {
189 | GError* error = NULL;
190 | GVariant* tmp = NULL;
191 | uint x = 0;
192 | uint y = 0;
193 |
194 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_output_workspace",
195 | g_variant_new("(u)", output_id),
196 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
197 | g_assert_no_error(error);
198 | g_variant_get(tmp, "(uu)", &x, &y);
199 | g_variant_unref(tmp);
200 |
201 | return std::pair{x, y};
202 | }
203 |
204 | static uint
205 | query_active_output ()
206 | {
207 | GError* error = NULL;
208 | GVariant* tmp = NULL;
209 | uint value = 0;
210 |
211 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_active_output", NULL,
212 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
213 | g_assert_no_error(error);
214 | g_variant_get(tmp, "(u)", &value);
215 | g_variant_unref(tmp);
216 |
217 | return value;
218 | }
219 |
220 | static uint
221 | query_view_role (uint view_id)
222 | {
223 | GError* error = NULL;
224 | GVariant* tmp = NULL;
225 | uint value = 0;
226 |
227 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_role",
228 | g_variant_new("(u)", view_id),
229 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
230 | g_assert_no_error(error);
231 | g_variant_get(tmp, "(u)", &value);
232 | g_variant_unref(tmp);
233 |
234 | return value;
235 | }
236 |
237 | static uint
238 | query_view_group_leader (uint view_id)
239 | {
240 | GError* error = NULL;
241 | GVariant* tmp = NULL;
242 | uint value;
243 |
244 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_group_leader",
245 | g_variant_new("(u)", view_id),
246 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
247 | g_assert_no_error(error);
248 | g_variant_get(tmp, "(u)", &value);
249 | g_variant_unref(tmp);
250 |
251 | return value;
252 | }
253 |
254 | static gchar*
255 | query_view_app_id (uint view_id)
256 | {
257 | GError* error = NULL;
258 | GVariant* tmp = NULL;
259 | gchar* value = NULL;
260 |
261 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_app_id",
262 | g_variant_new("(u)", view_id),
263 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
264 | g_assert_no_error(error);
265 | g_variant_get(tmp, "(s)", &value);
266 | g_variant_unref(tmp);
267 |
268 | return value;
269 | }
270 |
271 | static gchar*
272 | query_view_app_id_gtk_shell (uint view_id)
273 | {
274 | GError* error = NULL;
275 | GVariant* tmp = NULL;
276 | gchar* value = NULL;
277 |
278 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_app_id_gtk_shell",
279 | g_variant_new("(u)", view_id),
280 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
281 | g_assert_no_error(error);
282 | g_variant_get(tmp, "(s)", &value);
283 | g_variant_unref(tmp);
284 |
285 | return value;
286 | }
287 |
288 | static gchar*
289 | query_view_app_id_xwayland_net_wm_name (uint view_id)
290 | {
291 | GError* error = NULL;
292 | GVariant* tmp = NULL;
293 | gchar* value = NULL;
294 |
295 | tmp = g_dbus_proxy_call_sync(
296 | proxy->gobj(), "query_view_app_id_xwayland_net_wm_name",
297 | g_variant_new("(u)", view_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
298 | g_assert_no_error(error);
299 | g_variant_get(tmp, "(s)", &value);
300 | g_variant_unref(tmp);
301 |
302 | return value;
303 | }
304 |
305 | static gchar*
306 | query_view_title (uint view_id)
307 | {
308 | GError* error = NULL;
309 | GVariant* tmp = NULL;
310 | gchar* value = NULL;
311 |
312 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_title",
313 | g_variant_new("(u)", view_id),
314 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
315 | g_assert_no_error(error);
316 | g_variant_get(tmp, "(s)", &value);
317 | g_variant_unref(tmp);
318 |
319 | return value;
320 | }
321 |
322 | static int
323 | query_view_xwayland_atom_cardinal (uint view_id, const char* val)
324 | {
325 | GError* error = NULL;
326 | GVariant* tmp = NULL;
327 | int value;
328 |
329 | tmp =
330 | g_dbus_proxy_call_sync(proxy->gobj(), "query_view_xwayland_atom_cardinal",
331 | g_variant_new("(us)", view_id, val),
332 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
333 | g_assert_no_error(error);
334 | g_variant_get(tmp, "(u)", &value);
335 | g_variant_unref(tmp);
336 |
337 | return value;
338 | }
339 |
340 | static gboolean
341 | query_view_active (guint view_id)
342 | {
343 | GError* error = NULL;
344 | GVariant* tmp = NULL;
345 | gboolean value;
346 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_active",
347 | g_variant_new("(u)", view_id),
348 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
349 |
350 | g_assert_no_error(error);
351 | g_variant_get(tmp, "(b)", &value);
352 | g_variant_unref(tmp);
353 |
354 | return value;
355 | }
356 |
357 | static uint
358 | query_view_xwayland_wid (uint view_id)
359 | {
360 | GError* error = NULL;
361 | GVariant* tmp = NULL;
362 | uint value = 0;
363 |
364 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_xwayland_wid",
365 | g_variant_new("(u)", view_id),
366 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
367 | g_assert_no_error(error);
368 | g_variant_get(tmp, "(u)", &value);
369 | g_variant_unref(tmp);
370 |
371 | return value;
372 | }
373 |
374 | static void
375 | print_view_data (guint view_id)
376 | {
377 | // XXX: is there any point to free memory in such a short lived program?
378 | gchar* app_id = query_view_app_id(view_id);
379 | gchar* app_id_gtk = query_view_app_id_gtk_shell(view_id);
380 | gchar* title = query_view_title(view_id);
381 | gboolean minimized = query_view_minimized(view_id);
382 | gboolean maximized = query_view_maximized(view_id);
383 | gboolean fullscreened = query_view_fullscreen(view_id);
384 | gboolean active = query_view_active(view_id);
385 | guint above_id = query_view_above_view(view_id);
386 | guint below_id = query_view_below_view(view_id);
387 | gchar* above_app_id = query_view_app_id(above_id);
388 | gchar* below_app_id = query_view_app_id(below_id);
389 | guint output = query_view_output(view_id);
390 | gchar* output_name = query_output_name(output);
391 | guint xwid = query_view_xwayland_wid(view_id);
392 | guint role = query_view_role(view_id);
393 | guint group_leader = query_view_group_leader(view_id);
394 |
395 | std::vector> workspaces = query_view_workspaces(view_id);
396 | GError* error = NULL;
397 | GVariant* tmp = NULL;
398 | gint pid;
399 | guint uid;
400 | guint gid;
401 | tmp = g_dbus_proxy_call_sync(proxy->gobj(), "query_view_credentials",
402 | g_variant_new("(u)", view_id),
403 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
404 | g_assert_no_error(error);
405 | g_variant_get(tmp, "(iuu)", &pid, &uid, &gid);
406 | g_variant_unref(tmp);
407 |
408 | g_print("View Id: %u\n", view_id);
409 | g_print("App Id: [%s, %s]\n", app_id, app_id_gtk);
410 | g_print("Title: %s\n", title);
411 | if (role == 1) {
412 | g_print("Role: %s\n", "Toplevel Window");
413 | }
414 | else
415 | if (role == 2)
416 | {
417 | g_print("Role: %s\n", "Desktop Environment");
418 | }
419 | else
420 | if (role == 3)
421 | {
422 | g_print("Role: %s\n", "Unmanaged Window");
423 | }
424 | else
425 | {
426 | g_print("Role: %s\n", "Unknown");
427 | }
428 |
429 | g_print("Group Leader: %i\n", group_leader);
430 | g_print("Process id: %i\n", pid);
431 | g_print("User id: %u\n", uid);
432 | g_print("Group id: %u\n", gid);
433 | g_print("Active: %s\n", (active ? "True" : "False"));
434 | g_print("Minimized: %s\n", (minimized ? "True" : "False"));
435 | g_print("Maximized: %s\n", (maximized ? "True" : "False"));
436 | g_print("Fullscreen: %s\n", (fullscreened ? "True" : "False"));
437 | g_print("Workspaces: ");
438 |
439 | for (auto it = workspaces.begin(); it != workspaces.end(); ++it)
440 | {
441 | std::pair ws = *it;
442 | g_print("[%i, %i]", ws.first, ws.second);
443 | }
444 |
445 | g_print("\n");
446 | g_print("Output: [%u] %s\n", output, output_name);
447 | g_print("Above this view: [%i] %s\n", above_id,
448 | (above_id != -1 ? above_app_id : "None"));
449 | g_print("Below this view: [%i] %s\n", below_id,
450 | (below_id != -1 ? below_app_id : "None"));
451 |
452 | if (xwid == 0) {
453 | g_print("\n == This is a native wayland window ==\n");
454 | }
455 | else
456 | {
457 | g_print("\n == This is a xwayland window ==\n\n");
458 | std::stringstream stream;
459 | stream << std::hex << xwid;
460 | std::string result("0x" + stream.str());
461 | g_print("X Window id: %s\n", result.c_str());
462 | g_print("Run xwininfo -all -id %s and/or xprop -id %s for more "
463 | "information.\n",
464 | result.c_str(), result.c_str());
465 | }
466 | }
467 |
468 | static void
469 | on_signal (GDBusConnection* connection, const gchar* sender_name,
470 | const gchar* object_path, const gchar* interface_name,
471 | const gchar* signal_name, GVariant* parameters,
472 | gpointer user_data)
473 | {
474 | uint view_id;
475 | g_variant_get(parameters, "(u)", &view_id);
476 | uint _tmp = query_view_role(view_id);
477 |
478 | if ((_tmp != 1) && (_tmp != 2))
479 | {
480 | g_print("This surface is part of the desktop/compositor. Role: %u\n", _tmp);
481 | g_print("Please select another one.\n");
482 |
483 | return;
484 | }
485 |
486 | g_dbus_proxy_call_sync(proxy->gobj(), "enable_property_mode",
487 | g_variant_new("(b)", FALSE), G_DBUS_CALL_FLAGS_NONE,
488 | -1, NULL, NULL);
489 | print_view_data(view_id);
490 | exit(0);
491 | }
492 |
493 | static GOptionEntry entries [] = {
494 | {"list", 'l', 0, G_OPTION_ARG_NONE, &list,
495 | "List taskmanager related entries and exit",
496 | NULL},
497 | {NULL}
498 | };
499 |
500 | int
501 | main (int argc, char* argv [])
502 | {
503 | GError* error = NULL;
504 | GOptionContext* context;
505 | GMainLoop* loop;
506 |
507 | context = g_option_context_new("- get window properties");
508 | g_option_context_add_main_entries(context, entries, NULL);
509 |
510 | if (!g_option_context_parse(context, &argc, &argv, &error)) {
511 | g_print("%s\n", error->message);
512 | exit(1);
513 | }
514 |
515 | g_option_context_free(context);
516 | loop = g_main_loop_new(NULL, FALSE);
517 |
518 | Glib::RefPtr app = Gio::Application::create(
519 | "org.wayfire.wf-prop", Gio::APPLICATION_FLAGS_NONE);
520 |
521 | auto cancellable = Gio::Cancellable::create();
522 | connection =
523 | Gio::DBus::Connection::get_sync(Gio::DBus::BUS_TYPE_SESSION, cancellable);
524 |
525 | // g_main_loop_run(loop);
526 |
527 | if (!connection) {
528 | g_error("Failed to connect to dbus");
529 |
530 | return false;
531 | }
532 |
533 | proxy =
534 | Gio::DBus::Proxy::create_sync(connection, DBUS_ID, DBUS_PATH, DBUS_ID);
535 | if (!proxy) {
536 | g_error("Failed to connect to dbus interface");
537 |
538 | return false;
539 | }
540 |
541 | for (char** arg = argv; *arg; arg++)
542 | {
543 | if ((g_strcmp0(*arg, "l") == 0) || (g_strcmp0(*arg, "list") == 0)) {
544 | GVariant* value;
545 | GError* error = NULL;
546 |
547 | value = g_dbus_proxy_call_sync(proxy->gobj(),
548 | "query_view_vector_taskman_ids", NULL,
549 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
550 | g_assert_no_error(error);
551 | GVariantIter iter;
552 | GVariantIter iter2;
553 | GVariant* child;
554 | GVariant* cchild;
555 |
556 | g_variant_iter_init(&iter, value);
557 | while ((child = g_variant_iter_next_value(&iter)))
558 | {
559 | g_variant_iter_init(&iter2, child);
560 | while ((cchild = g_variant_iter_next_value(&iter2)))
561 | {
562 | g_print("***************************************\n");
563 | print_view_data(g_variant_get_uint32(cchild));
564 | g_print("***************************************\n\n");
565 | }
566 | }
567 |
568 | g_dbus_proxy_call_sync(proxy->gobj(), "enable_property_mode",
569 | g_variant_new("(b)", FALSE),
570 | G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
571 | g_assert_no_error(error);
572 | exit(0);
573 | }
574 | }
575 |
576 | g_dbus_connection_signal_subscribe(
577 | connection->gobj(), DBUS_ID, DBUS_ID, "view_pressed", DBUS_PATH,
578 | NULL, /* match rule */
579 | G_DBUS_SIGNAL_FLAGS_NONE, on_signal, NULL, /* user data */
580 | NULL);
581 |
582 | g_dbus_proxy_call_sync(proxy->gobj(), "enable_property_mode",
583 | g_variant_new("(b)", TRUE), G_DBUS_CALL_FLAGS_NONE, -1,
584 | NULL, &error);
585 | g_main_loop_run(loop);
586 | }
587 |
--------------------------------------------------------------------------------
/dbus_interface.cpp:
--------------------------------------------------------------------------------
1 | /*******************************************************************
2 | * This file is licensed under the MIT license.
3 | * Copyright (C) 2019 - 2020 Damian Ivanov
4 | ********************************************************************/
5 |
6 | #define HAS_CUSTOM 0
7 | #define DBUS_PLUGIN_DEBUG TRUE
8 | #define DBUS_PLUGIN_WARN TRUE
9 |
10 | extern "C" {
11 | #include
12 | #include
13 | };
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 |
41 | #include
42 |
43 | #include "dbus_interface_backend.cpp"
44 | gboolean geometry_signal = FALSE;
45 |
46 | static void
47 | settings_changed (GSettings* settings, const gchar* key,
48 | gpointer user_data)
49 | {
50 | if (g_strcmp0(key, "geometry-signal") == 0) {
51 | geometry_signal = g_settings_get_boolean(settings, "geometry-signal");
52 | }
53 | else
54 | {
55 | g_warning("No such settings %s", key);
56 | }
57 | }
58 |
59 | class dbus_interface_t
60 | {
61 | public:
62 | /************* Connect all signals for already existing objects
63 | * **************/
64 | dbus_interface_t()
65 | {
66 | #ifdef DBUS_PLUGIN_DEBUG
67 | LOG(wf::log::LOG_LEVEL_DEBUG, "Loading DBus Plugin");
68 | #endif
69 |
70 | settings = g_settings_new("org.wayland.compositor.dbus");
71 | for (wf::output_t* output : wf_outputs)
72 | {
73 | grab_interfaces[output] =
74 | std::make_unique (output);
75 | grab_interfaces[output]->name = "dbus";
76 | grab_interfaces[output]->capabilities = wf::CAPABILITY_GRAB_INPUT;
77 | output->connect_signal("view-mapped", &output_view_added);
78 |
79 | output->connect_signal("wm-actions-above-changed", &on_view_keep_above);
80 |
81 | output->connect_signal("output-configuration-changed",
82 | &output_configuration_changed);
83 |
84 | output->connect_signal("view-minimize-request", &output_view_minimized);
85 |
86 | output->connect_signal("view-tile-request", &output_view_maximized);
87 |
88 | output->connect_signal("view-move-request", &output_view_moving);
89 |
90 | output->connect_signal("view-resize-request", &output_view_resizing);
91 |
92 | output->connect_signal("view-change-viewport", &view_workspaces_changed);
93 |
94 | output->connect_signal("workspace-changed", &output_workspace_changed);
95 |
96 | output->connect_signal("view-layer-attached", &role_changed);
97 |
98 | output->connect_signal("view-layer-detached", &role_changed);
99 |
100 | output->connect_signal("view-focused", &output_view_focus_changed);
101 |
102 | output->connect_signal("view-fullscreen-request",
103 | &view_fullscreen_changed);
104 | #ifdef DBUS_PLUGIN_DEBUG
105 | LOG(wf::log::LOG_LEVEL_DEBUG, "output connected");
106 | #endif
107 | connected_wf_outputs.insert(output);
108 | }
109 |
110 | for (wayfire_view view : core.get_all_views())
111 | {
112 | view->connect_signal("app-id-changed", &view_app_id_changed);
113 |
114 | view->connect_signal("title-changed", &view_title_changed);
115 |
116 | view->connect_signal("geometry-changed", &view_geometry_changed);
117 |
118 | view->connect_signal("unmapped", &view_closed);
119 |
120 | view->connect_signal("tiled", &view_tiled);
121 |
122 | view->connect_signal("ping-timeout", &view_timeout);
123 |
124 | // view->connect_signal("subsurface-added", &subsurface_added);
125 | }
126 |
127 | /****************** Connect core signals ***********************/
128 |
129 | core.connect_signal("view-hints-changed", &view_hints_changed);
130 |
131 | core.connect_signal("view-focus-request", &view_focus_request);
132 |
133 | core.connect_signal("view-pre-moved-to-output",
134 | &view_output_move_requested);
135 |
136 | core.connect_signal("view-moved-to-output", &view_output_moved);
137 |
138 | core.connect_signal("pointer_button", &pointer_button_signal);
139 |
140 | core.connect_signal("tablet_button", &tablet_button_signal);
141 |
142 | core.output_layout->connect_signal("output-added",
143 | &output_layout_output_added);
144 |
145 | core.output_layout->connect_signal("output-removed",
146 | &output_layout_output_removed);
147 |
148 | g_signal_connect(settings, "changed", G_CALLBACK(settings_changed), NULL);
149 | geometry_signal = g_settings_get_boolean(settings, "geometry-signal");
150 |
151 | acquire_bus();
152 | gchar *startup_notify_cmd = NULL;
153 | startup_notify_cmd = g_settings_get_string(settings, "startup-notify");
154 | if (g_strcmp0(startup_notify_cmd, "") != 0) {
155 | LOG(wf::log::LOG_LEVEL_DEBUG, "Running startup up notify:",
156 | startup_notify_cmd);
157 | core.run(startup_notify_cmd);
158 | }
159 | g_free(startup_notify_cmd);
160 | }
161 |
162 | ~dbus_interface_t()
163 | {
164 | /*
165 | * There are probably a lot of things missing here.
166 | *
167 | * For my use-case it should never be unloaded.
168 | * Feel free to open PR for clean unloading.
169 | */
170 | #ifdef DBUS_PLUGIN_DEBUG
171 | LOG(wf::log::LOG_LEVEL_DEBUG, "Unloading DBus Plugin");
172 | #endif
173 |
174 | g_bus_unown_name(owner_id);
175 | g_dbus_node_info_unref(introspection_data);
176 | g_object_unref(settings);
177 | dbus_scale_filter::unload();
178 | }
179 |
180 | /******************************View Related Slots***************************/
181 | /***
182 | * A pointer button is interacted with
183 | ***/
184 | wf::signal_connection_t pointer_button_signal{[=] (wf::signal_data_t* data)
185 | {
186 | #ifdef DBUS_PLUGIN_DEBUG
187 | LOG(wf::log::LOG_LEVEL_DEBUG, "pointer_button_signal");
188 | #endif
189 | wf::pointf_t cursor_position;
190 | GVariant* signal_data;
191 | wf::input_event_signal* wf_ev;
192 | wlr_event_pointer_button* wlr_signal;
193 | wlr_button_state button_state;
194 | bool button_released;
195 | uint32_t button;
196 |
197 | cursor_position = core.get_cursor_position();
198 | wf_ev =
199 | static_cast*> (data);
200 | wlr_signal = static_cast (wf_ev->event);
201 | button_state = wlr_signal->state;
202 | button = wlr_signal->button;
203 | button_released = (button_state == WLR_BUTTON_RELEASED);
204 |
205 | if (find_view_under_action && button_released) {
206 | GVariant* _signal_data;
207 | wayfire_view view;
208 | view = core.get_view_at(cursor_position);
209 | _signal_data = g_variant_new("(u)", view ? view->get_id() : 0);
210 | g_variant_ref(_signal_data);
211 | bus_emit_signal("view_pressed", _signal_data);
212 | }
213 |
214 | signal_data = g_variant_new("(ddub)", cursor_position.x, cursor_position.y,
215 | button, button_released);
216 | g_variant_ref(signal_data);
217 | bus_emit_signal("pointer_clicked", signal_data);
218 | }
219 | };
220 |
221 | /***
222 | * A tablet button is interacted with
223 | * TODO: do more for touch events
224 | ***/
225 | wf::signal_connection_t tablet_button_signal{[=] (wf::signal_data_t* data)
226 | {
227 | #ifdef DBUS_PLUGIN_DEBUG
228 | LOG(wf::log::LOG_LEVEL_DEBUG, "tablet_button_signal");
229 | #endif
230 | bus_emit_signal("tablet_touched", nullptr);
231 | }
232 | };
233 |
234 | /***
235 | * A new view is added to an output.
236 | ***/
237 | wf::signal_connection_t output_view_added{[=] (wf::signal_data_t* data)
238 | {
239 | #ifdef DBUS_PLUGIN_DEBUG
240 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_view_added");
241 | #endif
242 |
243 | GVariant* signal_data;
244 | wayfire_view view;
245 |
246 | view = get_signaled_view(data);
247 | if (!view) {
248 | #ifdef DBUS_PLUGIN_DEBUG
249 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_view_added no view");
250 | #endif
251 |
252 | return;
253 | }
254 |
255 | signal_data = g_variant_new("(u)", view->get_id());
256 | g_variant_ref(signal_data);
257 | bus_emit_signal("view_added", signal_data);
258 |
259 | view->connect_signal("app-id-changed", &view_app_id_changed);
260 | view->connect_signal("title-changed", &view_title_changed);
261 | view->connect_signal("geometry-changed", &view_geometry_changed);
262 | view->connect_signal("unmapped", &view_closed);
263 | view->connect_signal("tiled", &view_tiled);
264 | view->connect_signal("ping-timeout", &view_timeout);
265 | // view->connect_signal("subsurface-added", &subsurface_added);
266 | }
267 | };
268 |
269 | // wf::signal_connection_t subsurface_added{[=](wf::signal_data_t *data) {
270 | // LOGE("subsurface_added signal");
271 | // }};
272 |
273 | /***
274 | * The View has received ping timeout.
275 | ***/
276 | wf::signal_connection_t view_timeout{[=] (wf::signal_data_t* data)
277 | {
278 | GVariant* signal_data;
279 | wayfire_view view;
280 | view = get_signaled_view(data);
281 |
282 | if (!view) {
283 | LOGE("view_timeout no view");
284 |
285 | return;
286 | }
287 |
288 | LOGE("view_timeout ", view->get_id());
289 |
290 | signal_data = g_variant_new("(u)", view->get_id());
291 | g_variant_ref(signal_data);
292 | bus_emit_signal("view_timeout", signal_data);
293 | }
294 | };
295 |
296 | /***
297 | * The view has closed.
298 | ***/
299 | wf::signal_connection_t view_closed{[=] (wf::signal_data_t* data)
300 | {
301 | #ifdef DBUS_PLUGIN_DEBUG
302 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_closed");
303 | #endif
304 |
305 | GVariant* signal_data;
306 | wayfire_view view;
307 |
308 | view = get_signaled_view(data);
309 |
310 | if (!view) {
311 | #ifdef DBUS_PLUGIN_DEBUG
312 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_closed no view");
313 | #endif
314 |
315 | return;
316 | }
317 |
318 | signal_data = g_variant_new("(u)", view->get_id());
319 | g_variant_ref(signal_data);
320 | bus_emit_signal("view_closed", signal_data);
321 | }
322 | };
323 |
324 | /***
325 | * The view's app_id has changed.
326 | ***/
327 | wf::signal_connection_t view_app_id_changed{[=] (wf::signal_data_t* data)
328 | {
329 | #ifdef DBUS_PLUGIN_DEBUG
330 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_app_id_changed");
331 | #endif
332 |
333 | GVariant* signal_data;
334 | wayfire_view view;
335 |
336 | view = get_signaled_view(data);
337 | if (!view) {
338 | #ifdef DBUS_PLUGIN_DEBUG
339 |
340 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_app_id_changed no view");
341 | #endif
342 |
343 | return;
344 | }
345 |
346 | signal_data =
347 | g_variant_new("(us)", view->get_id(), view->get_app_id().c_str());
348 | g_variant_ref(signal_data);
349 | bus_emit_signal("view_app_id_changed", signal_data);
350 | }
351 | };
352 |
353 | /***
354 | * The view's title has changed.
355 | ***/
356 | wf::signal_connection_t view_title_changed{[=] (wf::signal_data_t* data)
357 | {
358 | #ifdef DBUS_PLUGIN_DEBUG
359 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_title_changed");
360 | #endif
361 |
362 | GVariant* signal_data;
363 | wayfire_view view;
364 |
365 | view = get_signaled_view(data);
366 | if (!check_view_toplevel) {
367 | return;
368 | }
369 |
370 | signal_data =
371 | g_variant_new("(us)", view->get_id(), view->get_title().c_str());
372 | g_variant_ref(signal_data);
373 | bus_emit_signal("view_title_changed", signal_data);
374 | }
375 | };
376 |
377 | /***
378 | * The view's fullscreen status has changed.
379 | ***/
380 | wf::signal_connection_t view_fullscreen_changed{[=] (wf::signal_data_t* data)
381 | {
382 | #ifdef DBUS_PLUGIN_DEBUG
383 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_fullscreened");
384 | #endif
385 |
386 | wf::view_fullscreen_signal* signal;
387 | GVariant* signal_data;
388 | wayfire_view view;
389 |
390 | signal = static_cast (data);
391 | view = signal->view;
392 | signal_data = g_variant_new("(ub)", view->get_id(), signal->state);
393 | g_variant_ref(signal_data);
394 | bus_emit_signal("view_fullscreen_changed", signal_data);
395 | }
396 | };
397 |
398 | /***
399 | * The view's geometry has changed.
400 | ***/
401 | wf::signal_connection_t view_geometry_changed{[=] (wf::signal_data_t* data)
402 | {
403 | if (!geometry_signal) {
404 | return;
405 | }
406 |
407 | #ifdef DBUS_PLUGIN_DEBUG
408 |
409 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_geometry_changed");
410 | #endif
411 |
412 | GVariant* signal_data;
413 | wayfire_view view;
414 | wf::geometry_t geometry;
415 |
416 | view = get_signaled_view(data);
417 | geometry = view->get_output_geometry();
418 | signal_data = g_variant_new("(uiiii)", view->get_id(), geometry.x,
419 | geometry.y, geometry.width, geometry.height);
420 | g_variant_ref(signal_data);
421 | bus_emit_signal("view_geometry_changed", signal_data);
422 | }
423 | };
424 |
425 | /***
426 | * The view's tiling status has changed.
427 | ***/
428 | wf::signal_connection_t view_tiled{[=] (wf::signal_data_t* data)
429 | {
430 | #ifdef DBUS_PLUGIN_DEBUG
431 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_tiled");
432 | #endif
433 |
434 | GVariant* signal_data;
435 | wf::view_tiled_signal* signal;
436 | wayfire_view view;
437 |
438 | signal = static_cast (data);
439 | view = signal->view;
440 |
441 | if (!check_view_toplevel) {
442 | return;
443 | }
444 |
445 | signal_data = g_variant_new("(uu)", view->get_id(), signal->new_edges);
446 | g_variant_ref(signal_data);
447 | bus_emit_signal("view_tiling_changed", signal_data);
448 | }
449 | };
450 |
451 | /***
452 | * The view's output has changed.
453 | ***/
454 | wf::signal_connection_t view_output_moved{[=] (wf::signal_data_t* data)
455 | {
456 | #ifdef DBUS_PLUGIN_DEBUG
457 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_output_moved");
458 | #endif
459 |
460 | wf::view_moved_to_output_signal* signal;
461 | GVariant* signal_data;
462 | wayfire_view view;
463 | wf::output_t* old_output;
464 | wf::output_t* new_output;
465 |
466 | signal = static_cast (data);
467 | view = signal->view;
468 |
469 | if (!check_view_toplevel) {
470 | return;
471 | }
472 |
473 | old_output = signal->old_output;
474 | new_output = signal->new_output;
475 |
476 | signal_data = g_variant_new("(uuu)", view->get_id(), old_output->get_id(),
477 | new_output->get_id());
478 | g_variant_ref(signal_data);
479 | bus_emit_signal("view_output_moved", signal_data);
480 | }
481 | };
482 |
483 | /***
484 | * The view's output is about to change.
485 | ***/
486 | wf::signal_connection_t view_output_move_requested{
487 | [=] (wf::signal_data_t* data)
488 | {
489 | #ifdef DBUS_PLUGIN_DEBUG
490 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_output_move_requested");
491 | #endif
492 |
493 | GVariant* signal_data;
494 | wf::view_pre_moved_to_output_signal* signal;
495 | wf::output_t* old_output;
496 | wf::output_t* new_output;
497 | wayfire_view view;
498 |
499 | signal = static_cast (data);
500 | view = signal->view;
501 |
502 | if (view) {
503 | old_output = signal->old_output;
504 | new_output = signal->new_output;
505 | signal_data =
506 | g_variant_new("(uuu)", view->get_id(), old_output->get_id(),
507 | new_output->get_id());
508 | g_variant_ref(signal_data);
509 | bus_emit_signal("view_output_move_requested", signal_data);
510 | }
511 | }
512 | };
513 |
514 | /***
515 | * The view's role has changed.
516 | ***/
517 | wf::signal_connection_t role_changed{[=] (wf::signal_data_t* data)
518 | {
519 | #ifdef DBUS_PLUGIN_DEBUG
520 | LOG(wf::log::LOG_LEVEL_DEBUG, "role_changed");
521 | #endif
522 |
523 | GVariant* signal_data;
524 | wayfire_view view;
525 |
526 | view = get_signaled_view(data);
527 |
528 | if (!view) {
529 | #ifdef DBUS_PLUGIN_DEBUG
530 | LOG(wf::log::LOG_LEVEL_DEBUG, "role_changed no view");
531 | #endif
532 |
533 | return;
534 | }
535 |
536 | uint role = 0;
537 |
538 | if (view->role == wf::VIEW_ROLE_TOPLEVEL) {
539 | role = 1;
540 | }
541 | else
542 | if (view->role == wf::VIEW_ROLE_DESKTOP_ENVIRONMENT)
543 | {
544 | role = 2;
545 | }
546 | else
547 | if (view->role == wf::VIEW_ROLE_UNMANAGED)
548 | {
549 | role = 3;
550 | }
551 |
552 | signal_data = g_variant_new("(uu)", view->get_id(), role);
553 | g_variant_ref(signal_data);
554 | bus_emit_signal("view_role_changed", signal_data);
555 | }
556 | };
557 |
558 | /***
559 | * The view's workspaces have changed.
560 | ***/
561 | wf::signal_connection_t view_workspaces_changed{[=] (wf::signal_data_t* data)
562 | {
563 | #ifdef DBUS_PLUGIN_DEBUG
564 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_workspaces_changed");
565 | #endif
566 |
567 | GVariant* signal_data;
568 | view_change_viewport_signal* signal;
569 | wayfire_view view;
570 |
571 | signal = static_cast (data);
572 | view = signal->view;
573 |
574 | if (!check_view_toplevel) {
575 | return;
576 | }
577 |
578 | signal_data = g_variant_new("(u)", view->get_id());
579 |
580 | g_variant_ref(signal_data);
581 | bus_emit_signal("view_workspaces_changed", signal_data);
582 | }
583 | };
584 |
585 | /***
586 | * The view's maximized status has changed.
587 | ***/
588 | wf::signal_connection_t output_view_maximized{[=] (wf::signal_data_t* data)
589 | {
590 | #ifdef DBUS_PLUGIN_DEBUG
591 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_view_maximized");
592 | #endif
593 |
594 | wf::view_tiled_signal* signal;
595 | GVariant* signal_data;
596 | wayfire_view view;
597 | bool maximized;
598 |
599 | signal = static_cast (data);
600 | view = signal->view;
601 |
602 | if (!check_view_toplevel) {
603 | return;
604 | }
605 |
606 | maximized = (signal->new_edges == wf::TILED_EDGES_ALL);
607 | signal_data = g_variant_new("(ub)", view->get_id(), maximized);
608 | g_variant_ref(signal_data);
609 | bus_emit_signal("view_maximized_changed", signal_data);
610 | }
611 | };
612 |
613 | /***
614 | * The view's minimized status has changed.
615 | ***/
616 | wf::signal_connection_t output_view_minimized{[=] (wf::signal_data_t* data)
617 | {
618 | #ifdef DBUS_PLUGIN_DEBUG
619 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_view_minimized");
620 | #endif
621 |
622 | GVariant* signal_data;
623 | wf::view_minimize_request_signal* signal;
624 | wayfire_view view;
625 | bool minimized;
626 |
627 | signal = static_cast (data);
628 | view = signal->view;
629 |
630 | if (!check_view_toplevel) {
631 | return;
632 | }
633 |
634 | minimized = signal->state;
635 | signal_data = g_variant_new("(ub)", view->get_id(), minimized);
636 | g_variant_ref(signal_data);
637 | bus_emit_signal("view_minimized_changed", signal_data);
638 | }
639 | };
640 |
641 | /***
642 | * The view's focus has changed.
643 | ***/
644 | wf::signal_connection_t output_view_focus_changed{
645 | [=] (wf::signal_data_t* data)
646 | {
647 | GVariant* signal_data;
648 | wf::focus_view_signal* signal;
649 | wayfire_view view;
650 | uint view_id;
651 |
652 | signal = static_cast (data);
653 | view = signal->view;
654 |
655 | if (!check_view_toplevel) {
656 | return;
657 | }
658 |
659 | view_id = view->get_id();
660 |
661 | if (view_id == focused_view_id) {
662 | #ifdef DBUS_PLUGIN_DEBUG
663 | LOG(wf::log::LOG_LEVEL_DEBUG,
664 | "output_view_focus_changed old focus view");
665 | #endif
666 |
667 | return;
668 | }
669 |
670 | if (view->role != wf::VIEW_ROLE_TOPLEVEL) {
671 | #ifdef DBUS_PLUGIN_DEBUG
672 | LOG(wf::log::LOG_LEVEL_DEBUG,
673 | "output_view_focus_changed not a toplevel ");
674 | #endif
675 |
676 | return;
677 | }
678 |
679 | if (!view->activated) {
680 | return;
681 | }
682 |
683 | if (view->has_data("view-demands-attention")) {
684 | view->erase_data("view-demands-attention");
685 | }
686 |
687 | focused_view_id = view_id;
688 | signal_data = g_variant_new("(u)", view_id);
689 | g_variant_ref(signal_data);
690 | bus_emit_signal("view_focus_changed", signal_data);
691 | }
692 | };
693 |
694 | /***
695 | * The view hints demands focus
696 | * Examples:
697 | * 1) applications that get dbus activated
698 | * 2) Multiplayer games if game is found.
699 | * (source engine does this)
700 | ***/
701 | wf::signal_connection_t view_focus_request{[=] (wf::signal_data_t* data)
702 | {
703 | #ifdef DBUS_PLUGIN_DEBUG
704 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_focus_request_signal");
705 | #endif
706 | bool reconfigure = true;
707 | wf::view_focus_request_signal* signal;
708 | wayfire_view view;
709 | wf::output_t* active_output;
710 | wf::output_t* view_output;
711 |
712 | signal = static_cast (data);
713 | if (signal->carried_out) {
714 | return;
715 | }
716 |
717 | if (!signal->self_request) {
718 | return;
719 | }
720 |
721 | view = signal->view;
722 |
723 | if (!check_view_toplevel) {
724 | return;
725 | }
726 |
727 | active_output = core.get_active_output();
728 | view_output = view->get_output();
729 | // it is possible to also change the view''s
730 | // output e.g for single window applications
731 | // but other applications call sef_request_focus
732 | // for other reasons and this would change
733 | // it's output where it is completely undesired
734 | // if (view_output)
735 | // {
736 | // if (view_output != active_output)
737 | // {
738 | // }
739 | // }
740 |
741 | signal->carried_out = true;
742 | view->set_activated(true);
743 | view->focus_request();
744 | }
745 | };
746 |
747 | /***
748 | * The view hints have changed
749 | * The currently ownly interesting hint
750 | * is view-demands-attention
751 | ***/
752 | wf::signal_connection_t view_hints_changed{[=] (wf::signal_data_t* data)
753 | {
754 | wf::view_hints_changed_signal* signal;
755 | GVariant* signal_data;
756 | bool view_wants_attention = false;
757 | wayfire_view view;
758 |
759 | signal = static_cast (data);
760 | view = signal->view;
761 |
762 | if (!check_view_toplevel) {
763 | #ifdef DBUS_PLUGIN_DEBUG
764 |
765 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_hints_changed no view");
766 | #endif
767 |
768 | return;
769 | }
770 |
771 | #ifdef DBUS_PLUGIN_DEBUG
772 |
773 | LOG(wf::log::LOG_LEVEL_DEBUG, "view_hints_changed",
774 | view->has_data("view-demands-attention"));
775 | #endif
776 | if (view->has_data("view-demands-attention")) {
777 | view_wants_attention = true;
778 | }
779 |
780 | signal_data = g_variant_new("(ub)", view->get_id(), view_wants_attention);
781 | g_variant_ref(signal_data);
782 | bus_emit_signal("view_attention_changed", signal_data);
783 | }
784 | };
785 |
786 | /***
787 | * The view may or may not be moving now.
788 | * The status of that has somehow changed.
789 | * https://github.com/WayfireWM/wayfire/issues/639
790 | ***/
791 | wf::signal_connection_t output_view_moving{[=] (wf::signal_data_t* data)
792 | {
793 | #ifdef DBUS_PLUGIN_DEBUG
794 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_view_moving");
795 | #endif
796 |
797 | GVariant* signal_data;
798 | wayfire_view view;
799 |
800 | view = get_signaled_view(data);
801 |
802 | if (!check_view_toplevel) {
803 | return;
804 | }
805 |
806 | signal_data = g_variant_new("(u)", view->get_id());
807 | g_variant_ref(signal_data);
808 | bus_emit_signal("view_moving_changed", signal_data);
809 | }
810 | };
811 |
812 | /***
813 | * The view may or may not be resizing now.
814 | * The status of that has somehow changed.
815 | * https://github.com/WayfireWM/wayfire/issues/639
816 | ***/
817 | wf::signal_connection_t output_view_resizing{[=] (wf::signal_data_t* data)
818 | {
819 | #ifdef DBUS_PLUGIN_DEBUG
820 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_view_resizing");
821 | #endif
822 |
823 | GVariant* signal_data;
824 | wayfire_view view;
825 |
826 | view = get_signaled_view(data);
827 |
828 | if (!check_view_toplevel) {
829 | return;
830 | }
831 |
832 | signal_data = g_variant_new("(u)", view->get_id());
833 | g_variant_ref(signal_data);
834 | bus_emit_signal("view_resizing_changed", signal_data);
835 | }
836 | };
837 |
838 | /***
839 | * The wm-actions plugin changed the above_layer
840 | * state of a view.
841 | ***/
842 | wf::signal_connection_t on_view_keep_above{[=] (wf::signal_data_t* data)
843 | {
844 | GVariant* signal_data;
845 | wayfire_view view;
846 |
847 | view = wf::get_signaled_view(data);
848 |
849 | if (!check_view_toplevel) {
850 | return;
851 | }
852 |
853 | signal_data = g_variant_new("(ub)", view->get_id(),
854 | view->has_data("wm-actions-above"));
855 | g_variant_ref(signal_data);
856 | bus_emit_signal("view_keep_above_changed", signal_data);
857 | }
858 | };
859 |
860 | /***
861 | * The decoration of a view has changed
862 | ***/
863 | wf::signal_connection_t output_view_decoration_changed{
864 | [=] (wf::signal_data_t* data)
865 | {
866 | }
867 | };
868 |
869 | /***
870 | * No usecase has been found for these 3
871 | ***/
872 | wf::signal_connection_t output_detach_view{[=] (wf::signal_data_t* data)
873 | {
874 | }
875 | };
876 | wf::signal_connection_t output_view_disappeared{
877 | [=] (wf::signal_data_t* data)
878 | {
879 | }
880 | };
881 | wf::signal_connection_t output_view_attached{[=] (wf::signal_data_t* data)
882 | {
883 | }
884 | };
885 |
886 | /******************************Output Related
887 | * Slots***************************/
888 |
889 | /***
890 | * If the output configuration is changed somehow,
891 | * scaling / resolution etc changes, this is emitted
892 | ***/
893 | wf::signal_connection_t output_configuration_changed{
894 | [=] (wf::signal_data_t* data)
895 | {
896 | #ifdef DBUS_PLUGIN_DEBUG
897 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_configuration_changed");
898 | #endif
899 |
900 | bus_emit_signal("output_configuration_changed", nullptr);
901 | }
902 | };
903 |
904 | /***
905 | * The workspace of an output changed
906 | ***/
907 | wf::signal_connection_t output_workspace_changed{
908 | [=] (wf::signal_data_t* data)
909 | {
910 | #ifdef DBUS_PLUGIN_DEBUG
911 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_workspace_changed");
912 | #endif
913 |
914 | wf::workspace_changed_signal* signal;
915 | GVariant* signal_data;
916 | wf::output_t* output;
917 | int newHorizontalWorkspace;
918 | int newVerticalWorkspace;
919 |
920 | signal = static_cast (data);
921 | newHorizontalWorkspace = signal->new_viewport.x;
922 | newVerticalWorkspace = signal->new_viewport.y;
923 | output = signal->output;
924 | signal_data =
925 | g_variant_new("(uii)", output->get_id(), newHorizontalWorkspace,
926 | newVerticalWorkspace);
927 |
928 | g_variant_ref(signal_data);
929 | bus_emit_signal("output_workspace_changed", signal_data);
930 | }
931 | };
932 |
933 | /***
934 | * A new output has been added
935 | ***/
936 | wf::signal_connection_t output_layout_output_added{
937 | [=] (wf::signal_data_t* data)
938 | {
939 | #ifdef DBUS_PLUGIN_DEBUG
940 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_layout_output_added");
941 | #endif
942 | wf::output_t* output;
943 | GVariant* signal_data;
944 |
945 | output = get_signaled_output(data);
946 | auto search = connected_wf_outputs.find(output);
947 |
948 | if (search != connected_wf_outputs.end()) {
949 | return;
950 | }
951 |
952 | grab_interfaces[output] =
953 | std::make_unique (output);
954 | grab_interfaces[output]->name = "dbus";
955 | grab_interfaces[output]->capabilities = wf::CAPABILITY_GRAB_INPUT;
956 |
957 | output->connect_signal("wm-actions-above-changed", &on_view_keep_above);
958 |
959 | output->connect_signal("view-fullscreen-request",
960 | &view_fullscreen_changed);
961 |
962 | output->connect_signal("view-mapped", &output_view_added);
963 |
964 | output->connect_signal("output-configuration-changed",
965 | &output_configuration_changed);
966 |
967 | output->connect_signal("view-minimize-request", &output_view_minimized);
968 |
969 | output->connect_signal("view-tile-request", &output_view_maximized);
970 |
971 | output->connect_signal("view-move-request", &output_view_moving);
972 |
973 | output->connect_signal("view-change-viewport",
974 | &view_workspaces_changed);
975 |
976 | output->connect_signal("workspace-changed", &output_workspace_changed);
977 |
978 | output->connect_signal("view-resize-request", &output_view_resizing);
979 |
980 | output->connect_signal("view-focused", &output_view_focus_changed);
981 |
982 | output->connect_signal("view-layer-attached", &role_changed);
983 |
984 | output->connect_signal("view-layer-detached", &role_changed);
985 |
986 | wf_outputs = core.output_layout->get_outputs();
987 | connected_wf_outputs.insert(output);
988 |
989 | signal_data = g_variant_new("(u)", output->get_id());
990 | g_variant_ref(signal_data);
991 | bus_emit_signal("output_added", signal_data);
992 | }
993 | };
994 |
995 | /***
996 | * An output has been removed
997 | ***/
998 | wf::signal_connection_t output_layout_output_removed{
999 | [=] (wf::signal_data_t* data)
1000 | {
1001 | #ifdef DBUS_PLUGIN_DEBUG
1002 | LOG(wf::log::LOG_LEVEL_DEBUG, "output_layout_output_removed");
1003 | #endif
1004 | GVariant* signal_data;
1005 | wf::output_t* output;
1006 |
1007 | output = get_signaled_output(data);
1008 | auto search = connected_wf_outputs.find(output);
1009 |
1010 | if (search != connected_wf_outputs.end()) {
1011 | wf_outputs = core.output_layout->get_outputs();
1012 | connected_wf_outputs.erase(output);
1013 |
1014 | signal_data = g_variant_new("(u)", output->get_id());
1015 | g_variant_ref(signal_data);
1016 | bus_emit_signal("output_removed", signal_data);
1017 | }
1018 |
1019 | grab_interfaces.erase(output);
1020 |
1021 | // maybe use pre-removed instead?
1022 | }
1023 | };
1024 | };
1025 |
1026 | DECLARE_WAYFIRE_PLUGIN((wf::singleton_plugin_t));
1027 | // bool = unloadable
1028 |
--------------------------------------------------------------------------------
/uncrustify.ini:
--------------------------------------------------------------------------------
1 | # Uncrustify_d-0.71.0-21-d4da2b0f
2 |
3 | #
4 | # General options
5 | #
6 |
7 | # The type of line endings.
8 | #
9 | # Default: auto
10 | newlines = auto # lf/crlf/cr/auto
11 |
12 | # The original size of tabs in the input.
13 | #
14 | # Default: 8
15 | input_tab_size = 4 # unsigned number
16 |
17 | # The size of tabs in the output (only used if align_with_tabs=true).
18 | #
19 | # Default: 8
20 | output_tab_size = 3 # unsigned number
21 |
22 | # The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^).
23 | #
24 | # Default: 92
25 | string_escape_char = 92 # unsigned number
26 |
27 | # Alternate string escape char (usually only used for Pawn).
28 | # Only works right before the quote char.
29 | string_escape_char2 = 0 # unsigned number
30 |
31 | # Replace tab characters found in string literals with the escape sequence \t
32 | # instead.
33 | string_replace_tab_chars = true # true/false
34 |
35 | # Allow interpreting '>=' and '>>=' as part of a template in code like
36 | # 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken.
37 | # Improvements to template detection may make this option obsolete.
38 | tok_split_gte = false # true/false
39 |
40 | # Disable formatting of NL_CONT ('\\n') ended lines (e.g. multiline macros)
41 | disable_processing_nl_cont = false # true/false
42 |
43 | # Specify the marker used in comments to disable processing of part of the
44 | # file.
45 | # The comment should be used alone in one line.
46 | #
47 | # Default: *INDENT-OFF*
48 | disable_processing_cmt = " *INDENT-OFF*" # string
49 |
50 | # Specify the marker used in comments to (re)enable processing in a file.
51 | # The comment should be used alone in one line.
52 | #
53 | # Default: *INDENT-ON*
54 | enable_processing_cmt = " *INDENT-ON*" # string
55 |
56 | # Enable parsing of digraphs.
57 | enable_digraphs = false # true/false
58 |
59 | # Add or remove the UTF-8 BOM (recommend 'remove').
60 | utf8_bom = ignore # ignore/add/remove/force
61 |
62 | # If the file contains bytes with values between 128 and 255, but is not
63 | # UTF-8, then output as UTF-8.
64 | utf8_byte = false # true/false
65 |
66 | # Force the output encoding to UTF-8.
67 | utf8_force = false # true/false
68 |
69 | # Add or remove space between 'do' and '{'.
70 | sp_do_brace_open = add # ignore/add/remove/force
71 |
72 | # Add or remove space between '}' and 'while'.
73 | sp_brace_close_while = add # ignore/add/remove/force
74 |
75 | # Add or remove space between 'while' and '('.
76 | sp_while_paren_open = add # ignore/add/remove/force
77 |
78 | #
79 | # Spacing options
80 | #
81 |
82 | # Add or remove space around non-assignment symbolic operators ('+', '/', '%',
83 | # '<<', and so forth).
84 | sp_arith = force # ignore/add/remove/force
85 |
86 | # Add or remove space around assignment operator '=', '+=', etc.
87 | sp_assign = force # ignore/add/remove/force
88 |
89 | # Add or remove space around '=' in C++11 lambda capture specifications.
90 | #
91 | # Overrides sp_assign.
92 | sp_cpp_lambda_assign = remove # ignore/add/remove/force
93 |
94 | # Add or remove space after the capture specification of a C++11 lambda when
95 | # an argument list is present, as in '[] (int x){ ... }'.
96 | sp_cpp_lambda_square_paren = force # ignore/add/remove/force
97 |
98 | # Add or remove space after the capture specification of a C++11 lambda with
99 | # no argument list is present, as in '[] { ... }'.
100 | sp_cpp_lambda_square_brace = force # ignore/add/remove/force
101 |
102 | # Add or remove space after the argument list of a C++11 lambda, as in
103 | # '[](int x) { ... }'.
104 | sp_cpp_lambda_paren_brace = force # ignore/add/remove/force
105 |
106 | # Add or remove space in 'NS_ENUM ('.
107 | sp_enum_paren = ignore # ignore/add/remove/force
108 |
109 | # Add or remove space around assignment '=' in enum.
110 | sp_enum_assign = add # ignore/add/remove/force
111 |
112 | # Add or remove space around assignment ':' in enum.
113 | sp_enum_colon = add # ignore/add/remove/force
114 |
115 | # Add or remove space around boolean operators '&&' and '||'.
116 | sp_bool = add # ignore/add/remove/force
117 |
118 | # Add or remove space around compare operator '<', '>', '==', etc.
119 | sp_compare = force # ignore/add/remove/force
120 |
121 | # Add or remove space inside '(' and ')'.
122 | sp_inside_paren = remove # ignore/add/remove/force
123 |
124 | # Add or remove space between nested parentheses, i.e. '((' vs. ') )'.
125 | sp_paren_paren = remove # ignore/add/remove/force
126 |
127 | # Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('.
128 | sp_cparen_oparen = remove # ignore/add/remove/force
129 |
130 | # Add or remove space between ')' and '{'.
131 | sp_paren_brace = add # ignore/add/remove/force
132 |
133 | # Add or remove space between nested braces, i.e. '{{' vs '{ {'.
134 | sp_brace_brace = remove # ignore/add/remove/force
135 |
136 | # Add or remove space before pointer star '*'.
137 | sp_before_ptr_star = remove # ignore/add/remove/force
138 |
139 | # Add or remove space between pointer stars '*'.
140 | sp_between_ptr_star = remove # ignore/add/remove/force
141 |
142 | # Add or remove space after pointer star '*', if followed by a word.
143 | #
144 | # Overrides sp_type_func.
145 | sp_after_ptr_star = add # ignore/add/remove/force
146 |
147 | # Add or remove space before pointer star '*' that isn't followed by a
148 | # variable name. If set to ignore, sp_before_ptr_star is used instead.
149 | sp_before_unnamed_ptr_star = remove # ignore/add/remove/force
150 |
151 | # Add or remove space before a pointer star '*', if followed by a function
152 | # prototype or function definition.
153 | sp_before_ptr_star_func = remove # ignore/add/remove/force
154 |
155 | # Add or remove space before a reference sign '&'.
156 | sp_before_byref = remove # ignore/add/remove/force
157 |
158 | # Add or remove space after reference sign '&', if followed by a word.
159 | #
160 | # Overrides sp_type_func.
161 | sp_after_byref = add # ignore/add/remove/force
162 |
163 | # Add or remove space before a reference sign '&', if followed by a function
164 | # prototype or function definition.
165 | sp_before_byref_func = remove # ignore/add/remove/force
166 |
167 | # Add or remove space between 'decltype(...)' and word.
168 | sp_after_decltype = force # ignore/add/remove/force
169 |
170 | # Add or remove space before '<'.
171 | sp_before_angle = remove # ignore/add/remove/force
172 |
173 | # Add or remove space inside '<' and '>'.
174 | sp_inside_angle = remove # ignore/add/remove/force
175 |
176 | # Add or remove space inside '<>'.
177 | sp_inside_angle_empty = remove # ignore/add/remove/force
178 |
179 | # Add or remove space between '>' and ':'.
180 | sp_angle_colon = force # ignore/add/remove/force
181 |
182 | # Add or remove space after '>'.
183 | sp_after_angle = force # ignore/add/remove/force
184 |
185 | # Add or remove space between '>' and '(' as found in 'new List(foo);'.
186 | sp_angle_paren = add # ignore/add/remove/force
187 |
188 | # Add or remove space between '>' and '()' as found in 'new List();'.
189 | sp_angle_paren_empty = add # ignore/add/remove/force
190 |
191 | # Add or remove space between '>' and a word as in 'List m;' or
192 | # 'template static ...'.
193 | sp_angle_word = force # ignore/add/remove/force
194 |
195 | # Add or remove space between '>' and '>' in '>>' (template stuff).
196 | #
197 | # Default: add
198 | sp_angle_shift = remove # ignore/add/remove/force
199 |
200 | # (C++11) Permit removal of the space between '>>' in 'foo >'. Note
201 | # that sp_angle_shift cannot remove the space without this option.
202 | sp_permit_cpp11_shift = true # true/false
203 |
204 | # Add or remove space before '(' of control statements ('if', 'for', 'switch',
205 | # 'while', etc.).
206 | sp_before_sparen = add # ignore/add/remove/force
207 |
208 | # Add or remove space inside '(' and ')' of control statements.
209 | sp_inside_sparen = remove # ignore/add/remove/force
210 |
211 | # Add or remove space between ')' and '{' of of control statements.
212 | sp_sparen_brace = force # ignore/add/remove/force
213 |
214 | # Add or remove space before empty statement ';' on 'if', 'for' and 'while'.
215 | sp_special_semi = remove # ignore/add/remove/force
216 |
217 | # Add or remove space before ';' in non-empty 'for' statements.
218 | sp_before_semi_for = remove # ignore/add/remove/force
219 |
220 | # Add or remove space before a semicolon of an empty part of a for statement.
221 | sp_before_semi_for_empty = remove # ignore/add/remove/force
222 |
223 | # Add or remove space after ';', except when followed by a comment.
224 | #
225 | # Default: add
226 | sp_after_semi = remove # ignore/add/remove/force
227 |
228 | # Add or remove space after ';' in non-empty 'for' statements.
229 | #
230 | # Default: force
231 | sp_after_semi_for = force # ignore/add/remove/force
232 |
233 | # Add or remove space after the final semicolon of an empty part of a for
234 | # statement, as in 'for ( ; ; )'.
235 | sp_after_semi_for_empty = remove # ignore/add/remove/force
236 |
237 | # Add or remove space before '[' (except '[]').
238 | sp_before_square = remove # ignore/add/remove/force
239 |
240 | # Add or remove space before '[' for a variable definition.
241 | #
242 | # Default: remove
243 | sp_before_vardef_square = remove # ignore/add/remove/force
244 |
245 | # Add or remove space before '[]'.
246 | sp_before_squares = add # ignore/add/remove/force
247 |
248 | # Add or remove space before C++17 structured bindings.
249 | sp_cpp_before_struct_binding = force # ignore/add/remove/force
250 |
251 | # Add or remove space inside a non-empty '[' and ']'.
252 | sp_inside_square = remove # ignore/add/remove/force
253 |
254 | # Add or remove space after ',', i.e. 'a,b' vs. 'a, b'.
255 | sp_after_comma = force # ignore/add/remove/force
256 |
257 | # Add or remove space before the variadic '...' when preceded by a
258 | # non-punctuator.
259 | sp_before_ellipsis = remove # ignore/add/remove/force
260 |
261 | # Add or remove space between a type and '...'.
262 | sp_type_ellipsis = remove # ignore/add/remove/force
263 |
264 | # Add or remove space between ')' and '...'.
265 | sp_paren_ellipsis = remove # ignore/add/remove/force
266 |
267 | # Add or remove space between ')' and a qualifier such as 'const'.
268 | sp_paren_qualifier = force # ignore/add/remove/force
269 |
270 | # Add or remove space between ')' and 'noexcept'.
271 | sp_paren_noexcept = force # ignore/add/remove/force
272 |
273 | # Add or remove space after class ':'.
274 | sp_after_class_colon = force # ignore/add/remove/force
275 |
276 | # Add or remove space before class ':'.
277 | sp_before_class_colon = force # ignore/add/remove/force
278 |
279 | # Add or remove space after class constructor ':'.
280 | sp_after_constr_colon = force # ignore/add/remove/force
281 |
282 | # Add or remove space before class constructor ':'.
283 | sp_before_constr_colon = force # ignore/add/remove/force
284 |
285 | # Add or remove space between 'operator' and operator sign.
286 | sp_after_operator = force # ignore/add/remove/force
287 |
288 | # Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or
289 | # '(int)a' vs. '(int) a'.
290 | sp_after_cast = remove # ignore/add/remove/force
291 |
292 | # Add or remove spaces inside cast parentheses.
293 | sp_inside_paren_cast = remove # ignore/add/remove/force
294 |
295 | # Add or remove space between the type and open parenthesis in a C++ cast,
296 | # i.e. 'int(exp)' vs. 'int (exp)'.
297 | sp_cpp_cast_paren = remove # ignore/add/remove/force
298 |
299 | # Add or remove space between 'sizeof' and '('.
300 | sp_sizeof_paren = add # ignore/add/remove/force
301 |
302 | # Add or remove space between 'sizeof' and '...'.
303 | sp_sizeof_ellipsis = remove # ignore/add/remove/force
304 |
305 | # Add or remove space between 'sizeof...' and '('.
306 | sp_sizeof_ellipsis_paren = add # ignore/add/remove/force
307 |
308 | # Add or remove space between 'decltype' and '('.
309 | sp_decltype_paren = add # ignore/add/remove/force
310 |
311 | # Add or remove space after open brace in an unnamed temporary
312 | # direct-list-initialization.
313 | sp_after_type_brace_init_lst_open = remove # ignore/add/remove/force
314 |
315 | # Add or remove space before close brace in an unnamed temporary
316 | # direct-list-initialization.
317 | sp_before_type_brace_init_lst_close = remove # ignore/add/remove/force
318 |
319 | # Add or remove space inside '{}'.
320 | sp_inside_braces_empty = remove # ignore/add/remove/force
321 |
322 | # Add or remove space around trailing return operator '->'.
323 | sp_trailing_return = add # ignore/add/remove/force
324 |
325 | # Add or remove space between type and open brace of an unnamed temporary
326 | # direct-list-initialization.
327 | sp_type_brace_init_lst = remove # ignore/add/remove/force
328 |
329 | # Add or remove space between function name and '(' on function declaration.
330 | sp_func_proto_paren = add # ignore/add/remove/force
331 |
332 | # Add or remove space between function name and '()' on function declaration
333 | # without parameters.
334 | sp_func_proto_paren_empty = add # ignore/add/remove/force
335 |
336 | # Add or remove space between function name and '(' with a typedef specifier.
337 | sp_func_type_paren = add # ignore/add/remove/force
338 |
339 | # Add or remove space between alias name and '(' of a non-pointer function type typedef.
340 | sp_func_def_paren = add # ignore/add/remove/force
341 |
342 | # Add or remove space between function name and '()' on function definition
343 | # without parameters.
344 | sp_func_def_paren_empty = add # ignore/add/remove/force
345 |
346 | # Add or remove space inside empty function '()'.
347 | # Overrides sp_after_angle unless use_sp_after_angle_always is set to true.
348 | sp_inside_fparens = remove # ignore/add/remove/force
349 |
350 | # Add or remove space inside function '(' and ')'.
351 | sp_inside_fparen = remove # ignore/add/remove/force
352 |
353 | # Add or remove space inside the first parentheses in a function type, as in
354 | # 'void (*x)(...)'.
355 | sp_inside_tparen = add # ignore/add/remove/force
356 |
357 | # Add or remove space between ']' and '(' when part of a function call.
358 | sp_square_fparen = remove # ignore/add/remove/force
359 |
360 | # Add or remove space between ')' and '{' of function.
361 | sp_fparen_brace = force # ignore/add/remove/force
362 |
363 | # Add or remove space between function name and '(' on function calls.
364 | sp_func_call_paren = remove # ignore/add/remove/force
365 |
366 | # Add or remove space between a constructor/destructor and the open
367 | # parenthesis.
368 | sp_func_class_paren = remove # ignore/add/remove/force
369 |
370 | # Add or remove space between a constructor without parameters or destructor
371 | # and '()'.
372 | sp_func_class_paren_empty = remove # ignore/add/remove/force
373 |
374 | # Add or remove space between 'return' and '('.
375 | sp_return_paren = force # ignore/add/remove/force
376 |
377 | # Add or remove space between 'return' and '{'.
378 | sp_return_brace = force # ignore/add/remove/force
379 |
380 | # Add or remove space between '__attribute__' and '('.
381 | sp_attribute_paren = remove # ignore/add/remove/force
382 |
383 | # Add or remove space between 'defined' and '(' in '#if defined (FOO)'.
384 | sp_defined_paren = force # ignore/add/remove/force
385 |
386 | # Add or remove space between 'throw' and '(' in 'throw (something)'.
387 | sp_throw_paren = force # ignore/add/remove/force
388 |
389 | # Add or remove space between 'throw' and anything other than '(' as in
390 | # '@throw [...];'.
391 | sp_after_throw = force # ignore/add/remove/force
392 |
393 | # Add or remove space between 'catch' and '(' in 'catch (something) { }'.
394 | # If set to ignore, sp_before_sparen is used.
395 | sp_catch_paren = force # ignore/add/remove/force
396 |
397 | # Add or remove space between a macro function ')' and its definition.
398 | sp_macro_func = add # ignore/add/remove/force
399 |
400 | # Add or remove space between 'else' and '{' if on the same line.
401 | sp_else_brace = force # ignore/add/remove/force
402 |
403 | # Add or remove space between '}' and 'else' if on the same line.
404 | sp_brace_else = force # ignore/add/remove/force
405 |
406 | # Add or remove space between '}' and the name of a typedef on the same line.
407 | sp_brace_typedef = force # ignore/add/remove/force
408 |
409 | # Add or remove space before the '{' of a 'catch' statement, if the '{' and
410 | # 'catch' are on the same line, as in 'catch (decl) {'.
411 | sp_catch_brace = force # ignore/add/remove/force
412 |
413 | # Add or remove space between '}' and 'catch' if on the same line.
414 | sp_brace_catch = force # ignore/add/remove/force
415 |
416 | # Add or remove space between 'try' and '{' if on the same line.
417 | sp_try_brace = force # ignore/add/remove/force
418 |
419 | # Add or remove space between a variable and '{' for C++ uniform
420 | # initialization.
421 | sp_word_brace_init_lst = remove # ignore/add/remove/force
422 |
423 | # Add or remove space before the '::' operator.
424 | sp_before_dc = remove # ignore/add/remove/force
425 |
426 | # Add or remove space after the '::' operator.
427 | sp_after_dc = remove # ignore/add/remove/force
428 |
429 | # Add or remove space before a backslash-newline at the end of a line.
430 | #
431 | # Default: add
432 | sp_before_nl_cont = add # ignore/add/remove/force
433 |
434 | # Add or remove space around the ':' in 'b ? t : f'.
435 | sp_cond_colon = force # ignore/add/remove/force
436 |
437 | # Add or remove space around the '?' in 'b ? t : f'.
438 | sp_cond_question = force # ignore/add/remove/force
439 |
440 | # In the abbreviated ternary form '(a ?: b)', add or remove space between '?'
441 | # and ':'.
442 | #
443 | # Overrides all other sp_cond_* options.
444 | sp_cond_ternary_short = remove # ignore/add/remove/force
445 |
446 | # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make
447 | # sense here.
448 | sp_case_label = force # ignore/add/remove/force
449 |
450 | # Add or remove space after ':' in a Java/C++11 range-based 'for',
451 | # as in 'for (Type var : expr)'.
452 | sp_after_for_colon = force # ignore/add/remove/force
453 |
454 | # Add or remove space before ':' in a Java/C++11 range-based 'for',
455 | # as in 'for (Type var : expr)'.
456 | sp_before_for_colon = force # ignore/add/remove/force
457 |
458 | # Add or remove space after the opening of a C++ comment,
459 | # i.e. '// A' vs. '//A'.
460 | sp_cmt_cpp_start = force # ignore/add/remove/force
461 |
462 | # Add or remove space between #else or #endif and a trailing comment.
463 | sp_endif_cmt = force # ignore/add/remove/force
464 |
465 | # Add or remove space after 'new', 'delete' and 'delete[]'.
466 | sp_after_new = force # ignore/add/remove/force
467 |
468 | # Add or remove space between 'new' and '(' in 'new()'.
469 | sp_between_new_paren = remove # ignore/add/remove/force
470 |
471 | # Add or remove space between ')' and type in 'new(foo) BAR'.
472 | sp_after_newop_paren = force # ignore/add/remove/force
473 |
474 | # Add or remove space inside parenthesis of the new operator
475 | # as in 'new(foo) BAR'.
476 | sp_inside_newop_paren = remove # ignore/add/remove/force
477 |
478 | # Add or remove space before a trailing or embedded comment.
479 | sp_before_tr_emb_cmt = force # ignore/add/remove/force
480 |
481 | # Number of spaces before a trailing or embedded comment.
482 | sp_num_before_tr_emb_cmt = 1 # unsigned number
483 |
484 | #
485 | # Indenting options
486 | #
487 |
488 | # The number of columns to indent per level. Usually 2, 3, 4, or 8.
489 | #
490 | # Default: 8
491 | indent_columns = 4 # unsigned number
492 |
493 | # The continuation indent. If non-zero, this overrides the indent of '(', '['
494 | # and '=' continuation indents. Negative values are OK; negative value is
495 | # absolute and not increased for each '(' or '[' level.
496 | #
497 | # For FreeBSD, this is set to 4.
498 | indent_continue = 0 # number
499 |
500 | # How to use tabs when indenting code.
501 | #
502 | # 0: Spaces only
503 | # 1: Indent with tabs to brace level, align with spaces (default)
504 | # 2: Indent and align with tabs, using spaces when not on a tabstop
505 | #
506 | # Default: 1
507 | indent_with_tabs = 0 # unsigned number
508 |
509 | # Whether to indent strings broken by '\' so that they line up.
510 | indent_align_string = true # true/false
511 |
512 | # Whether the 'extern "C"' body is indented.
513 | indent_extern = true # true/false
514 |
515 | # Whether the 'class' body is indented.
516 | indent_class = true # true/false
517 |
518 | # Whether to indent the stuff after a leading base class colon.
519 | indent_class_colon = false # true/false
520 |
521 | # Whether to indent based on a class colon instead of the stuff after the
522 | # colon. Requires indent_class_colon=true.
523 | indent_class_on_colon = true # true/false
524 |
525 | # Whether to indent the stuff after a leading class initializer colon.
526 | indent_constr_colon = false # true/false
527 |
528 | # Virtual indent from the ':' for member initializers.
529 | #
530 | # Default: 2
531 | indent_ctor_init_leading = 2 # unsigned number
532 |
533 | # Whether to indent continued variable declarations instead of aligning.
534 | indent_var_def_cont = false # true/false
535 |
536 | # Whether to indent continued function call parameters one indent level,
537 | # rather than aligning parameters under the open parenthesis.
538 | indent_func_call_param = false # true/false
539 |
540 | # Whether to indent continued function definition parameters one indent level,
541 | # rather than aligning parameters under the open parenthesis.
542 | indent_func_def_param = false # true/false
543 |
544 | # Whether to indent continued function call prototype one indent level,
545 | # rather than aligning parameters under the open parenthesis.
546 | indent_func_proto_param = false # true/false
547 |
548 | # Whether to indent continued function call declaration one indent level,
549 | # rather than aligning parameters under the open parenthesis.
550 | indent_func_class_param = false # true/false
551 |
552 | # Whether to indent continued class variable constructors one indent level,
553 | # rather than aligning parameters under the open parenthesis.
554 | indent_func_ctor_var_param = false # true/false
555 |
556 | # Whether to indent continued template parameter list one indent level,
557 | # rather than aligning parameters under the open parenthesis.
558 | indent_template_param = false # true/false
559 |
560 | # Whether lines broken at '.' or '->' should be indented by a single indent.
561 | # The indent_member option will not be effective if this is set to true.
562 | indent_member_single = true # true/false
563 |
564 | # Whether to indent trailing single line ('//') comments relative to the code
565 | # instead of trying to keep the same absolute column.
566 | indent_relative_single_line_comments = true # true/false
567 |
568 | # Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns.
569 | indent_switch_case = 0 # unsigned number
570 |
571 | # Spaces to shift the 'case' line, without affecting any other lines.
572 | # Usually 0.
573 | indent_case_shift = 2 # unsigned number
574 |
575 | # How to indent access specifiers that are followed by a
576 | # colon.
577 | #
578 | # >0: Absolute column where 1 is the leftmost column
579 | # <=0: Subtract from brace indent
580 | #
581 | # Default: 1
582 | indent_access_spec = -2 # number
583 |
584 | # How to indent a close parenthesis after a newline.
585 | #
586 | # 0: Indent to body level (default)
587 | # 1: Align under the open parenthesis
588 | # 2: Indent to the brace level
589 | indent_paren_close = 1 # unsigned number
590 |
591 | # Whether to align continued statements at the '='. If false or if the '=' is
592 | # followed by a newline, the next line is indent one tab.
593 | #
594 | # Default: true
595 | indent_align_assign = false # true/false
596 |
597 | # Whether to align continued statements at the '('. If false or the '(' is
598 | # followed by a newline, the next line indent is one tab.
599 | #
600 | # Default: true
601 | indent_align_paren = false # true/false
602 |
603 | # How to indent after a brace followed by another token (not a newline).
604 | # true: indent all contained lines to match the token
605 | # false: indent all contained lines to match the brace
606 | #
607 | # Default: true
608 | indent_token_after_brace = false # true/false
609 |
610 | # Whether to indent the body of a C++11 lambda.
611 | indent_cpp_lambda_body = false # true/false
612 | #
613 | #
614 | # Newline adding and removing options
615 | #
616 |
617 | # Whether to collapse empty blocks between '{' and '}'.
618 | nl_collapse_empty_body = false # true/false
619 |
620 | # Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'.
621 | nl_assign_leave_one_liners = true # true/false
622 |
623 | # Don't split one-line C++11 lambdas, as in '[]() { return 0; }'.
624 | nl_cpp_lambda_leave_one_liners = false # true/false
625 |
626 | # Add or remove newlines at the start of the file.
627 | nl_start_of_file = remove # ignore/add/remove/force
628 |
629 | # Add or remove newline at the end of the file.
630 | nl_end_of_file = remove # ignore/add/remove/force
631 |
632 | # The minimum number of newlines at the end of the file (only used if
633 | # nl_end_of_file is 'add' or 'force').
634 | nl_end_of_file_min = 1 # unsigned number
635 |
636 | # Add or remove newline between '=' and '{'.
637 | nl_assign_brace = add # ignore/add/remove/force
638 |
639 | # Add or remove newline between a function call's ')' and '{', as in
640 | # 'list_for_each(item, &list) { }'.
641 | nl_fcall_brace = add # ignore/add/remove/force
642 |
643 | # Add or remove newline between 'enum' and '{'.
644 | nl_enum_brace = add # ignore/add/remove/force
645 |
646 | # Add or remove newline between 'enum' and 'class'.
647 | nl_enum_class = add # ignore/add/remove/force
648 |
649 | # Add or remove newline between 'enum class' and the identifier.
650 | nl_enum_class_identifier = force # ignore/add/remove/force
651 |
652 | # Add or remove newline between 'enum class' type and ':'.
653 | nl_enum_identifier_colon = remove # ignore/add/remove/force
654 |
655 | # Add or remove newline between 'struct and '{'.
656 | nl_struct_brace = add # ignore/add/remove/force
657 |
658 | # Add or remove newline between 'union' and '{'.
659 | nl_union_brace = add # ignore/add/remove/force
660 |
661 | # Add or remove newline between 'if' and '{'.
662 | nl_if_brace = ignore # ignore/add/remove/force
663 |
664 | # Add or remove newline between '}' and 'else'.
665 | nl_brace_else = add # ignore/add/remove/force
666 |
667 | # Add or remove newline between 'else if' and '{'. If set to ignore,
668 | # nl_if_brace is used instead.
669 | nl_elseif_brace = add # ignore/add/remove/force
670 |
671 | # Add or remove newline between 'else' and '{'.
672 | nl_else_brace = add # ignore/add/remove/force
673 |
674 | # Add or remove newline between 'else' and 'if'.
675 | nl_else_if = add # ignore/add/remove/force
676 |
677 | # Add or remove newline before '{' opening brace
678 | nl_before_opening_brace_func_class_def = add # ignore/add/remove/force
679 |
680 | # Add or remove newline before 'if'/'else if' closing parenthesis.
681 | nl_before_if_closing_paren = remove # ignore/add/remove/force
682 |
683 | # Add or remove newline between 'try' and '{'.
684 | nl_try_brace = add # ignore/add/remove/force
685 |
686 | # Add or remove newline between 'for' and '{'.
687 | nl_for_brace = add # ignore/add/remove/force
688 |
689 | # Add or remove newline before the '{' of a 'catch' statement, as in
690 | # 'catch (decl) {'.
691 | nl_catch_brace = add # ignore/add/remove/force
692 |
693 | # Add or remove newline between '}' and 'catch'.
694 | nl_brace_catch = add # ignore/add/remove/force
695 |
696 | # Add or remove newline between '}' and ')' in a function invocation.
697 | nl_brace_fparen = remove # ignore/add/remove/force
698 |
699 | # Add or remove newline between 'while' and '{'.
700 | nl_while_brace = add # ignore/add/remove/force
701 |
702 | # Add or remove newline between two open or close braces. Due to general
703 | # newline/brace handling, REMOVE may not work.
704 | nl_brace_brace = add # ignore/add/remove/force
705 |
706 | # Add or remove newline between 'do' and '{'.
707 | nl_do_brace = add # ignore/add/remove/force
708 |
709 | # Add or remove newline between '}' and 'while' of 'do' statement.
710 | nl_brace_while = add # ignore/add/remove/force
711 |
712 | # Add or remove newline between 'switch' and '{'.
713 | nl_switch_brace = add # ignore/add/remove/force
714 |
715 | # Force a newline in a define after the macro name for multi-line defines.
716 | nl_multi_line_define = true # true/false
717 |
718 | # Whether to add a newline before 'case', and a blank line before a 'case'
719 | # statement that follows a ';' or '}'.
720 | nl_before_case = true # true/false
721 |
722 | # Whether to add a newline after a 'case' statement.
723 | nl_after_case = true # true/false
724 |
725 | # Add or remove newline between 'namespace' and '{'.
726 | nl_namespace_brace = true # ignore/add/remove/force
727 |
728 | # Add or remove newline after 'template<...>' of a template class.
729 | nl_template_class = force # ignore/add/remove/force
730 |
731 | # Add or remove newline after 'template<...>' of a template function.
732 | nl_template_func = force # ignore/add/remove/force
733 |
734 | # Add or remove newline between 'class' and '{'.
735 | nl_class_brace = force # ignore/add/remove/force
736 |
737 | # Add or remove newline before first element, after comma, and after last
738 | # element, in 'enum'.
739 | nl_enum_own_lines = add # ignore/add/remove/force
740 |
741 | # Add or remove newline between return type and function name in a function
742 | # definition.
743 | # might be modified by nl_func_leave_one_liners
744 | nl_func_type_name = add # ignore/add/remove/force
745 |
746 | # Add or remove newline between class specification and '::'
747 | # in 'void A::f() { }'. Only appears in separate member implementation (does
748 | # not appear with in-line implementation).
749 | nl_func_class_scope = remove # ignore/add/remove/force
750 |
751 | # Add or remove newline between function scope and name, as in
752 | # 'void A :: f() { }'.
753 | nl_func_scope_name = add # ignore/add/remove/force
754 |
755 | # Add or remove newline between return type and function name in a prototype.
756 | nl_func_proto_type_name = add # ignore/add/remove/force
757 |
758 | # Add or remove newline between a function name and the opening '(' in the
759 | # declaration.
760 | nl_func_paren = remove # ignore/add/remove/force
761 |
762 | # Add or remove newline between a function name and the opening '(' in the
763 | # definition.
764 | nl_func_def_paren = remove # ignore/add/remove/force
765 |
766 | # Add or remove newline between a function name and the opening '(' in the
767 | # call.
768 | nl_func_call_paren = remove # ignore/add/remove/force
769 |
770 | # Add or remove newline after each ',' in a function declaration.
771 | nl_func_decl_args = ignore # ignore/add/remove/force
772 |
773 | # Add or remove newline after each ',' in a function definition.
774 | nl_func_def_args = ignore # ignore/add/remove/force
775 |
776 | # Add or remove newline after each ',' in a function call.
777 | nl_func_call_args = ignore # ignore/add/remove/force
778 |
779 | # Add or remove newline before the ')' in a function declaration.
780 | nl_func_decl_end = remove # ignore/add/remove/force
781 |
782 | # Add or remove newline before the ')' in a function definition.
783 | nl_func_def_end = remove # ignore/add/remove/force
784 |
785 | # Add or remove newline between '()' in a function declaration.
786 | nl_func_decl_empty = remove # ignore/add/remove/force
787 |
788 | # Add or remove newline between '()' in a function definition.
789 | nl_func_def_empty = remove # ignore/add/remove/force
790 |
791 | # Add or remove newline between '()' in a function call.
792 | nl_func_call_empty = remove # ignore/add/remove/force
793 |
794 | # Whether to add a newline before ')' in a function call.
795 | nl_func_call_end = remove # ignore/add/remove/force
796 |
797 | # Add or remove newline between function signature and '{'.
798 | nl_fdef_brace = true # ignore/add/remove/force
799 |
800 | # Add or remove newline between C++11 lambda signature and '{'.
801 | nl_cpp_ldef_brace = add # ignore/add/remove/force
802 |
803 | # Whether to add a newline after semicolons, except in 'for' statements.
804 | nl_after_semicolon = true # true/false
805 |
806 | # Whether to add a newline after '{'. This also adds a newline before the
807 | # matching '}'.
808 | nl_after_brace_open = true # true/false
809 |
810 | # Whether to add a newline between the open brace and a trailing single-line
811 | # comment. Requires nl_after_brace_open=true.
812 | nl_after_brace_open_cmt = true # true/false
813 |
814 | # Whether to add a newline after '}'. Does not apply if followed by a
815 | # necessary ';'.
816 | nl_after_brace_close = true # true/false
817 |
818 | # Whether to add a newline after a virtual brace close,
819 | # as in 'if (foo) a++; return;'.
820 | nl_after_vbrace_close = true # true/false
821 |
822 | # Add or remove newline between the close brace and identifier,
823 | # as in 'struct { int a; } b;'. Affects enumerations, unions and
824 | # structures. If set to ignore, uses nl_after_brace_close.
825 | nl_brace_struct_var = remove # ignore/add/remove/force
826 |
827 | # Add or remove blank line after 'if' statement. Add/Force work only if the
828 | # next token is not a closing brace.
829 | nl_after_if = force # ignore/add/remove/force
830 |
831 | # Add or remove blank line after 'for' statement.
832 | nl_after_for = force # ignore/add/remove/force
833 |
834 | # Add or remove blank line after 'while' statement.
835 | nl_after_while = force # ignore/add/remove/force
836 |
837 | # Add or remove blank line after 'switch' statement.
838 | nl_after_switch = force # ignore/add/remove/force
839 |
840 | # Add or remove blank line after 'do/while' statement.
841 | nl_after_do = force # ignore/add/remove/force
842 |
843 | # Whether to put a blank line before 'return' statements, unless after an open
844 | # brace.
845 | nl_before_return = true # true/false
846 |
847 | # Whether to force a newline before '}' of a 'struct'/'union'/'enum'.
848 | # (Lower priority than eat_blanks_before_close_brace.)
849 | nl_ds_struct_enum_close_brace = true # true/false
850 |
851 |
852 | # Blank line options
853 | #
854 |
855 | # The maximum number of consecutive newlines (3 = 2 blank lines).
856 | nl_max = 2 # unsigned number
857 |
858 | # The maximum number of consecutive newlines in a function.
859 | nl_max_blank_in_func = 2 # unsigned number
860 |
861 | # The number of newlines after '}' of a multi-line function body.
862 | nl_after_func_body = 2 # unsigned number
863 |
864 | # The number of newlines after '}' of a multi-line function body in a class
865 | # declaration. Also affects class constructors/destructors.
866 | #
867 | # Overrides nl_after_func_body.
868 | nl_after_func_body_class = 2 # unsigned number
869 |
870 | # The number of newlines after '}' or ';' of a struct/enum/union definition.
871 | nl_after_struct = 2 # unsigned number
872 |
873 | # The number of newlines after '}' or ';' of a class definition.
874 | nl_after_class = 2 # unsigned number
875 |
876 | # The number of newlines after '}' of a namespace.
877 | nl_after_namespace = 2 # unsigned number
878 |
879 | # The number of newlines before an access specifier label. This also includes
880 | # the Qt-specific 'signals:' and 'slots:'. Will not change the newline count
881 | # if after a brace open.
882 | #
883 | # 0: No change (default).
884 | nl_before_access_spec = 2 # unsigned number
885 |
886 | # The number of newlines after a try-catch-finally block that isn't followed
887 | # by a brace close.
888 | #
889 | # 0: No change (default).
890 | nl_after_try_catch_finally = 2 # unsigned number
891 |
892 | # Whether to remove blank lines after '{'.
893 | eat_blanks_after_open_brace = true # true/false
894 |
895 | # Whether to remove blank lines before '}'.
896 | eat_blanks_before_close_brace = true # true/false
897 |
898 | #
899 | # Positioning options
900 | #
901 |
902 | # The position of arithmetic operators in wrapped expressions.
903 | pos_arith = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
904 |
905 | # The position of assignment in wrapped expressions. Do not affect '='
906 | # followed by '{'.
907 | pos_assign = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
908 |
909 | # The position of Boolean operators in wrapped expressions.
910 | pos_bool = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
911 |
912 | # The position of comparison operators in wrapped expressions.
913 | pos_compare = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
914 |
915 | # The position of conditional operators, as in the '?' and ':' of
916 | # 'expr ? stmt : stmt', in wrapped expressions.
917 | pos_conditional = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
918 |
919 | # The position of the comma in wrapped expressions.
920 | pos_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
921 |
922 | # The position of the comma in enum entries.
923 | pos_enum_comma = trail_force # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
924 |
925 | # The position of the comma in the base class list if there is more than one
926 | # line. Affects nl_class_init_args.
927 | pos_class_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
928 |
929 | # The position of the comma in the constructor initialization list.
930 | # Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon.
931 | pos_constr_comma = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
932 |
933 | # The position of trailing/leading class colon, between class and base class
934 | # list. Affects nl_class_colon.
935 | pos_class_colon = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
936 |
937 | # The position of colons between constructor and member initialization.
938 | # Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma.
939 | pos_constr_colon = trail # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force
940 |
941 | #
942 | # Code alignment options (not left column spaces/tabs)
943 | #
944 |
945 | # The span for aligning on '=' in assignments.
946 | #
947 | # 0: Don't align (default).
948 | align_assign_span = 0 # unsigned number
949 | align_assign_thresh = -4 # number
950 |
951 | align_enum_equ_span = 4 # unsigned number
952 | align_enum_equ_thresh = -20 # number
953 |
954 | align_number_right = true # true/false
955 | #
956 | # Line splitting options
957 | #
958 |
959 | # Try to limit code width to N columns.
960 | code_width = 0 # unsigned number
961 |
962 | # Whether to fully split long 'for' statements at semi-colons.
963 | ls_for_split_full = true # true/false
964 |
965 | # Whether to fully split long function prototypes/calls at commas.
966 | # The option ls_code_width has priority over the option ls_func_split_full.
967 | ls_func_split_full = false # true/false
968 |
969 | # Whether to split lines as close to code_width as possible and ignore some
970 | # groupings.
971 | # The option ls_code_width has priority over the option ls_func_split_full.
972 | ls_code_width = false # true/false
973 |
974 | #
975 | # Comment modification options
976 | #
977 |
978 | # Try to wrap comments at N columns.
979 | cmt_width = 85 # unsigned number
980 |
981 | # How to reflow comments.
982 | #
983 | # 0: No reflowing (apart from the line wrapping due to cmt_width) (default)
984 | # 1: No touching at all
985 | # 2: Full reflow
986 | cmt_reflow_mode = 2 # unsigned number
987 |
988 | # Whether to convert all tabs to spaces in comments. If false, tabs in
989 | # comments are left alone, unless used for indenting.
990 | cmt_convert_tab_to_spaces = true # true/false
991 |
992 | # Whether to group c-comments that look like they are in a block.
993 | cmt_c_group = true # true/false
994 |
995 | # Whether to put a star on subsequent comment lines.
996 | cmt_star_cont = true # true/false
997 |
998 | # Whether to put an empty '/*' on the first line of the combined c-comment.
999 | cmt_c_nl_start = true # true/false
1000 |
1001 | # Whether to add a newline before the closing '*/' of the combined c-comment.
1002 | cmt_c_nl_end = true # true/false
1003 |
1004 | # The number of spaces to insert at the start of subsequent comment lines.
1005 | cmt_sp_before_star_cont = 0 # unsigned number
1006 |
1007 | # The number of spaces to insert after the star on subsequent comment lines.
1008 | cmt_sp_after_star_cont = 1 # unsigned number
1009 |
1010 | #
1011 | # Code modifying options (non-whitespace)
1012 | #
1013 |
1014 | # Add or remove braces on a single-line 'do' statement.
1015 | mod_full_brace_do = force # ignore/add/remove/force
1016 |
1017 | # Add or remove braces on a single-line 'for' statement.
1018 | mod_full_brace_for = force # ignore/add/remove/force
1019 |
1020 | # (Pawn) Add or remove braces on a single-line function definition.
1021 | mod_full_brace_function = force # ignore/add/remove/force
1022 |
1023 | # Add or remove braces on a single-line 'if' statement. Braces will not be
1024 | # removed if the braced statement contains an 'else'.
1025 | mod_full_brace_if = force # ignore/add/remove/force
1026 |
1027 | # Whether to add braces to all blocks of an 'if'/'else if'/'else' chain.
1028 | # If true, mod_full_brace_if_chain will only remove braces from an 'if' that
1029 | # does not have an 'else if' or 'else'.
1030 | mod_full_brace_if_chain_only = true # true/false
1031 |
1032 | # Add or remove braces on single-line 'while' statement.
1033 | mod_full_brace_while = force # ignore/add/remove/force
1034 |
1035 | # Whether to fully parenthesize Boolean expressions in 'while' and 'if'
1036 | # statement, as in 'if (a && b > c)' => 'if (a && (b > c))'.
1037 | mod_full_paren_if_bool = true # true/false
1038 |
1039 | # Whether to remove superfluous semicolons.
1040 | mod_remove_extra_semicolon = true # true/false
1041 |
1042 | # If an #ifdef body exceeds the specified number of newlines and doesn't have
1043 | # a comment after the #endif, a comment will be added.
1044 | mod_add_long_ifdef_endif_comment = 0 # unsigned number
1045 |
1046 | # If an #ifdef or #else body exceeds the specified number of newlines and
1047 | # doesn't have a comment after the #else, a comment will be added.
1048 | mod_add_long_ifdef_else_comment = 0 # unsigned number
1049 |
1050 | # Whether to remove a void 'return;' that appears as the last statement in a
1051 | # function.
1052 | mod_remove_empty_return = false # true/false
1053 |
1054 | # Add or remove the comma after the last value of an enumeration.
1055 | mod_enum_last_comma = force # ignore/add/remove/force
1056 |
1057 | #
1058 | # Preprocessor options
1059 | #
1060 |
1061 | # Add or remove indentation of preprocessor directives inside #if blocks
1062 | # at brace level 0 (file-level).
1063 | pp_indent = add # ignore/add/remove/force
1064 |
1065 | # Whether to indent the code between #if, #else and #endif.
1066 | pp_if_indent_code = false # true/false
1067 |
1068 | # Use or Do not Use options
1069 | #
1070 |
1071 | # true: indent_func_call_param will be used (default)
1072 | # false: indent_func_call_param will NOT be used
1073 | #
1074 | # Default: true
1075 | use_indent_func_call_param = true # true/false
1076 |
1077 | # The value of the indentation for a continuation line is calculated
1078 | # differently if the statement is:
1079 | # - a declaration: your case with QString fileName ...
1080 | # - an assignment: your case with pSettings = new QSettings( ...
1081 | #
1082 | # At the second case the indentation value might be used twice:
1083 | # - at the assignment
1084 | # - at the function call (if present)
1085 | #
1086 | # To prevent the double use of the indentation value, use this option with the
1087 | # value 'true'.
1088 | #
1089 | # true: indent_continue will be used only once
1090 | # false: indent_continue will be used every time (default)
1091 | use_indent_continue_only_once = true # true/false
1092 |
1093 | # The value might be used twice:
1094 | # - at the assignment
1095 | # - at the opening brace
1096 | #
1097 | # To prevent the double use of the indentation value, use this option with the
1098 | # value 'true'.
1099 | #
1100 | # true: indentation will be used only once
1101 | # false: indentation will be used every time (default)
1102 | indent_cpp_lambda_only_once = false # true/false
1103 |
1104 | # Whether sp_after_angle takes precedence over sp_inside_fparen. This was the
1105 | # historic behavior, but is probably not the desired behavior, so this is off
1106 | # by default.
1107 | use_sp_after_angle_always = false # true/false
1108 |
--------------------------------------------------------------------------------
/dbus_interface_backend.cpp:
--------------------------------------------------------------------------------
1 | /*******************************************************************
2 | * This file is licensed under the MIT license.
3 | * Copyright (C) 2019 - 2020 Damian Ivanov
4 | ********************************************************************/
5 | #define DBUS_PLUGIN_DEBUG TRUE
6 | #define DBUS_PLUGIN_WARN TRUE
7 |
8 | extern "C" {
9 | #define class class_t
10 | #define static
11 | #include
12 | #include
13 | #include
14 | #include
15 | // #include
16 | #undef static
17 | #undef class
18 | #include
19 | #include
20 | };
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include
29 |
30 | #include "dbus_scale_filter.hpp"
31 | #include "wayfire/view-transform.hpp"
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 |
49 | wf::option_wrapper_t xwayland_enabled("core/xwayland");
50 |
51 | wf::compositor_core_t& core = wf::get_core();
52 | std::vector wf_outputs = core.output_layout->get_outputs();
53 | std::set connected_wf_outputs;
54 | GSettings* settings;
55 | std::map>
56 | grab_interfaces;
57 |
58 | uint focused_view_id;
59 | bool find_view_under_action = false;
60 | GDBusNodeInfo* introspection_data = nullptr;
61 | GDBusConnection* dbus_connection;
62 | uint owner_id;
63 |
64 | static gboolean
65 | check_view_toplevel (wayfire_view view)
66 | {
67 | if (!view) {
68 | return FALSE;
69 | }
70 |
71 | if (!view->is_mapped()) {
72 | return FALSE;
73 | }
74 |
75 | if (view->role != wf::VIEW_ROLE_TOPLEVEL) {
76 | return FALSE;
77 | }
78 |
79 | if (!view->get_output()) {
80 | return FALSE;
81 | }
82 |
83 | return TRUE;
84 | }
85 |
86 | static wayfire_view
87 | get_view_from_view_id (uint view_id)
88 | {
89 | std::vector view_vector;
90 | wayfire_view view;
91 |
92 | view_vector = core.get_all_views();
93 |
94 | // there is no view_id 0 use it as get_active_view(hint)
95 | if (view_id == 0) {
96 | view = core.get_cursor_focus_view();
97 | if (check_view_toplevel(view)) {
98 | return view;
99 | }
100 | }
101 |
102 | for (auto it = view_vector.begin(); it != view_vector.end(); ++it)
103 | {
104 | wayfire_view v = *it;
105 | if (check_view_toplevel(v)) {
106 | if (v->get_id() == view_id) {
107 | return v;
108 | }
109 | }
110 | }
111 |
112 | return view;
113 | }
114 |
115 | static wf::output_t*
116 | get_output_from_output_id (uint output_id)
117 | {
118 | for (wf::output_t* wf_output : wf_outputs)
119 | {
120 | if (wf_output->get_id() == output_id) {
121 | return wf_output;
122 | }
123 | }
124 |
125 | return nullptr;
126 | }
127 |
128 | static void
129 | restack_view (uint view_id, uint related_view_id, gboolean above)
130 | {
131 | if (view_id == related_view_id) {
132 | return;
133 | }
134 |
135 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
136 | idle_call->run_once([=] ()
137 | {
138 | wayfire_view view = get_view_from_view_id(view_id);
139 | wayfire_view related_view = get_view_from_view_id(related_view_id);
140 |
141 | if (!check_view_toplevel(view) || !check_view_toplevel(related_view)) {
142 | delete idle_call;
143 |
144 | return;
145 | }
146 |
147 | wf::output_t* output = view->get_output();
148 | if (!output) {
149 | delete idle_call;
150 |
151 | return;
152 | }
153 |
154 | if (above) {
155 | view->get_output()->workspace->restack_above(view, related_view);
156 | }
157 | else
158 | {
159 | view->get_output()->workspace->restack_below(view, related_view);
160 | }
161 |
162 | delete idle_call;
163 | });
164 | }
165 |
166 | /*
167 | * It is a deliberate design choice to have
168 | * methods / signals instead of properties
169 | *
170 | * Not all clients fully support
171 | * automatic property change notifcations!
172 | */
173 | const gchar introspection_xml [] =
174 | ""
175 | " "
176 | // ""
177 | // kept as example
178 | /************************* Methods ************************/
179 | // Draft methods
180 | // " "
181 | // " "
182 |
183 | // " "
184 | // " "
185 |
186 | " "
187 | " "
188 | " "
189 | " "
190 | " "
191 | " "
192 | " "
193 |
194 | /************************* Output Methods ************************/
195 | " "
196 | " "
197 | " "
198 | " "
199 | " "
200 | " "
201 | " "
202 | " "
203 | " "
204 | " "
205 | " "
206 | " "
207 | " "
208 | " "
209 | " "
210 | " "
211 | " "
212 | " "
213 | " "
214 | " "
215 | " "
216 | " "
217 | " "
218 | " "
219 | " "
220 | " "
221 | " "
222 | " "
223 | " "
224 | " "
225 | /************************* View Methods ************************/
226 | " "
227 | " "
228 | " "
229 | " "
230 | " "
231 | " "
232 | " "
233 | " "
234 | " "
235 | " "
236 | " "
237 | " "
238 | " "
239 | " "
240 | " "
241 | " "
242 | " "
243 | " "
244 | " "
245 | " "
246 | " "
247 | " "
248 | " "
249 | " "
250 | " "
251 | " "
252 | " "
253 | " "
254 | " "
255 | " "
256 | " "
257 | " "
258 | " "
259 | " "
260 | " "
261 | " "
262 | " "
263 | " "
264 | " "
265 | " "
266 | " "
267 | " "
268 | " "
269 | " "
270 | " "
271 | " "
272 | " "
273 | " "
274 | " "
275 | " "
276 | " "
277 | " "
278 | " "
279 | " "
280 | " "
281 | " "
282 | " "
283 | " "
284 | " "
285 | " "
286 | " "
287 | " "
288 | " "
289 | " "
290 | " "
291 | " "
292 | " "
293 | " "
294 | " "
295 | " "
296 | " "
297 | " "
298 | " "
299 | " "
300 | " "
301 | " "
302 | " "
303 | " "
304 | " "
305 | " "
306 | " "
307 | " "
308 | " "
309 | " "
310 | " "
311 | " "
312 | " "
313 | " "
314 | " "
315 | " "
316 | " "
317 | " "
318 | " "
319 | " "
320 | " "
321 | " "
322 | " "
323 | " "
324 | " "
325 | " "
326 | " "
327 | " "
328 | " "
329 | " "
330 | " "
331 | " "
332 | " "
333 | " "
334 | " "
335 | " "
336 | " "
337 | " "
338 | " "
339 | " "
340 | " "
341 | " "
342 | " "
343 | " "
344 | " "
345 | " "
346 | " "
347 | " "
348 | " "
349 | " "
350 | " "
351 | " "
352 | " "
353 | " "
354 | " "
355 | " "
356 | " "
357 | " "
358 | " "
359 | " "
360 | " "
361 | " "
362 | " "
363 | " "
364 | " "
365 | " "
366 | " "
367 | " "
368 | " "
369 | " "
370 | " "
371 | " "
372 | " "
373 | " "
374 | " "
375 | " "
376 | " "
377 | " "
378 | " "
379 | " "
380 | " "
381 | " "
382 | " "
383 | " "
384 | " "
385 | " "
386 | " "
387 | " "
388 | " "
389 | " "
390 | " "
391 | " "
392 | " "
393 | " "
394 | " "
395 | " "
396 | " "
397 | " "
398 | " "
399 | " "
400 | " "
401 | /************************* Signals ************************/
402 | /***
403 | * Core Input Signals
404 | ***/
405 | " "
406 | " "
407 | " "
408 | " "
409 | " "
410 | " "
411 | " "
412 |
413 | /***
414 | * View related signals, emitted from various
415 | * sources
416 | ***/
417 | " "
418 | " "
419 | " "
420 | " "
421 | " "
422 | " "
423 | " "
424 | " "
425 | " "
426 | " "
427 | " "
428 | " "
429 | " "
430 | " "
431 | " "
432 | " "
433 | " "
434 | " "
435 | " "
436 | " "
437 | " "
438 | " "
439 | " "
440 | " "
441 | " "
442 | " "
443 | " "
444 | " "
445 | " "
446 | " "
447 | " "
448 | " "
449 | " "
450 | " "
451 | " "
452 | " "
453 | " "
454 | " "
455 | " "
456 | " "
457 | " "
458 | " "
459 | " "
460 | " "
461 | " "
462 | " "
463 | " "
464 | " "
465 | " "
466 | " "
467 | " "
468 | " "
469 | " "
470 | " "
471 | " "
472 | " "
473 | " "
474 | " "
475 | " "
476 | " "
477 | " "
478 | " "
479 | " "
480 | " "
481 | " "
482 | " "
483 | " "
484 | " "
485 | " "
486 | " "
487 | " "
488 | " "
489 | " "
490 | " "
491 | " "
492 | /***
493 | * Output related signals, emitted from various
494 | * sources
495 | ***/
496 | " "
497 | " "
498 | " "
499 | " "
500 | " "
501 | " "
502 | " "
503 | " "
504 | " "
505 | " "
506 | " "
507 | " "
508 |
509 | /***
510 | * For wf-prop & co
511 | ***/
512 | " "
513 | " "
514 | " "
515 | /***
516 | * Tentative signals
517 | * " "
518 | * " "
519 | * " "
520 | * " "
521 | * " "
522 | * " "
523 | * " "
524 | * " "
525 | * " "
526 | *
527 | * " "
528 | * " "
529 | ***/
530 |
531 | " "
532 | "";
533 |
534 | static void
535 | handle_method_call (GDBusConnection* connection, const gchar* sender,
536 | const gchar* object_path,
537 | const gchar* interface_name,
538 | const gchar* method_name, GVariant* parameters,
539 | GDBusMethodInvocation* invocation,
540 | gpointer user_data)
541 | {
542 | #ifdef DBUS_PLUGIN_DEBUG
543 | LOG(wf::log::LOG_LEVEL_DEBUG, "handle_method_call bus called ", method_name);
544 | #endif
545 |
546 | if (g_strcmp0(method_name, "change_view_above") == 0) {
547 | uint view_id;
548 | uint action;
549 |
550 | g_variant_get(parameters, "(uu)", &view_id, &action);
551 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
552 | idle_call->run_once([=] ()
553 | {
554 | wayfire_view view = get_view_from_view_id(view_id);
555 | if (!check_view_toplevel(view)) {
556 | delete idle_call;
557 |
558 | return;
559 | }
560 |
561 | bool is_above;
562 | wf::output_t* output;
563 | wf::_view_signal signal_data;
564 | is_above = view->has_data("wm-actions-above");
565 | output = view->get_output();
566 |
567 | if ((action == 0) && is_above) {
568 | signal_data.view = view;
569 | output->emit_signal("wm-actions-toggle-above", &signal_data);
570 | }
571 | else
572 | if ((action == 1) && !is_above)
573 | {
574 | signal_data.view = view;
575 | output->emit_signal("wm-actions-toggle-above", &signal_data);
576 | }
577 | else
578 | if (action == 2)
579 | {
580 | signal_data.view = view;
581 | output->emit_signal("wm-actions-toggle-above", &signal_data);
582 | }
583 |
584 | delete idle_call;
585 | });
586 |
587 | g_dbus_method_invocation_return_value(invocation, NULL);
588 |
589 | return;
590 | }
591 |
592 | /*************** View Actions ****************/
593 | else
594 | if (g_strcmp0(method_name, "ensure_view_visible") == 0)
595 | {
596 | uint view_id;
597 | g_variant_get(parameters, "(u)", &view_id);
598 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
599 | idle_call->run_once([=] ()
600 | {
601 | wayfire_view view = get_view_from_view_id(view_id);
602 |
603 | if (check_view_toplevel(view)) {
604 | view->get_output()->ensure_visible(view);
605 | }
606 |
607 | delete idle_call;
608 | });
609 | g_dbus_method_invocation_return_value(invocation, NULL);
610 |
611 | return;
612 | }
613 | else
614 | if (g_strcmp0(method_name, "update_view_minimize_hint") == 0)
615 | {
616 | uint view_id;
617 | g_variant_get(parameters, "(u)", &view_id);
618 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
619 | idle_call->run_once([=] ()
620 | {
621 | wayfire_view view = get_view_from_view_id(view_id);
622 |
623 | if (check_view_toplevel(view)) {
624 | wf::pointf_t pos;
625 | pos = core.get_active_output()->get_cursor_position();
626 | view->set_minimize_hint({(int)pos.x, (int)pos.y, 5, 5});
627 | }
628 |
629 | delete idle_call;
630 | });
631 | g_dbus_method_invocation_return_value(invocation, NULL);
632 |
633 | return;
634 | }
635 | else
636 | if (g_strcmp0(method_name, "shade_view") == 0)
637 | {
638 | uint view_id;
639 | double intensity;
640 |
641 | g_variant_get(parameters, "(ud)", &view_id, &intensity);
642 |
643 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
644 | idle_call->run_once([=] ()
645 | {
646 | wayfire_view view = get_view_from_view_id(view_id);
647 | if (!check_view_toplevel(view)) {
648 | delete idle_call;
649 |
650 | return;
651 | }
652 |
653 | if (intensity == 1.0) {
654 | if (view->get_transformer("dbus-shade")) {
655 | view->pop_transformer("dbus-shade");
656 | }
657 | }
658 | else
659 | {
660 | wf::view_2D* transformer;
661 | if (!view->get_transformer("dbus-shade")) {
662 | view->add_transformer(std::make_unique (view),
663 | "dbus-shade");
664 | }
665 |
666 | transformer = dynamic_cast (
667 | view->get_transformer("dbus-shade").get());
668 |
669 | if (transformer->alpha != (float)intensity) {
670 | transformer->alpha = (float)intensity;
671 | // view->damage();
672 | }
673 | }
674 |
675 | delete idle_call;
676 | });
677 | g_dbus_method_invocation_return_value(invocation, NULL);
678 |
679 | return;
680 | }
681 | else
682 | if (g_strcmp0(method_name, "bring_view_to_front") == 0)
683 | {
684 | uint view_id;
685 | g_variant_get(parameters, "(u)", &view_id);
686 |
687 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
688 | idle_call->run_once([=] ()
689 | {
690 | wayfire_view view = get_view_from_view_id(view_id);
691 |
692 | if (check_view_toplevel(view)) {
693 | wf::output_t* output = view->get_output();
694 | output->workspace->bring_to_front(view);
695 | }
696 |
697 | delete idle_call;
698 | });
699 |
700 | g_dbus_method_invocation_return_value(invocation, NULL);
701 |
702 | return;
703 | }
704 | else
705 | if (g_strcmp0(method_name, "restack_view_above") == 0)
706 | {
707 | uint view_id;
708 | uint related_view_id;
709 | g_variant_get(parameters, "(uu)", &view_id, &related_view_id);
710 | restack_view(view_id, related_view_id, TRUE);
711 | g_dbus_method_invocation_return_value(invocation, NULL);
712 |
713 | return;
714 | }
715 | else
716 | if (g_strcmp0(method_name, "restack_view_below") == 0)
717 | {
718 | uint view_id;
719 | uint related_view_id;
720 | g_variant_get(parameters, "(uu)", &view_id, &related_view_id);
721 | restack_view(view_id, related_view_id, FALSE);
722 | g_dbus_method_invocation_return_value(invocation, NULL);
723 |
724 | return;
725 | }
726 | else
727 | if (g_strcmp0(method_name, "minimize_view") == 0)
728 | {
729 | uint view_id;
730 | uint action;
731 |
732 | g_variant_get(parameters, "(uu)", &view_id, &action);
733 |
734 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
735 | idle_call->run_once([=] ()
736 | {
737 | wayfire_view view = get_view_from_view_id(view_id);
738 | if (!check_view_toplevel(view)) {
739 | delete idle_call;
740 |
741 | return;
742 | }
743 |
744 | if ((action == 0) && view->minimized) {
745 | view->minimize_request(false);
746 | }
747 |
748 | else
749 | if ((action == 1) && !view->minimized)
750 | {
751 | view->minimize_request(true);
752 | }
753 |
754 | else
755 | if (action == 2)
756 | {
757 | view->minimize_request(!view->minimized);
758 | }
759 |
760 | delete idle_call;
761 | });
762 |
763 | g_dbus_method_invocation_return_value(invocation, NULL);
764 |
765 | return;
766 | }
767 | else
768 | if (g_strcmp0(method_name, "maximize_view") == 0)
769 | {
770 | uint view_id;
771 | uint action;
772 | g_variant_get(parameters, "(uu)", &view_id, &action);
773 |
774 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
775 | idle_call->run_once([=] ()
776 | {
777 | wayfire_view view = get_view_from_view_id(view_id);
778 | if (!check_view_toplevel(view)) {
779 | delete idle_call;
780 |
781 | return;
782 | }
783 |
784 | if (action == 0) {
785 | view->tile_request(0);
786 | }
787 |
788 | else
789 | if (action == 1)
790 | {
791 | view->tile_request(wf::TILED_EDGES_ALL);
792 | }
793 |
794 | else
795 | if (action == 2)
796 | {
797 | if (view->tiled_edges == wf::TILED_EDGES_ALL) {
798 | view->tile_request(0);
799 | }
800 | else
801 | {
802 | view->tile_request(wf::TILED_EDGES_ALL);
803 | }
804 | }
805 |
806 | delete idle_call;
807 | });
808 | g_dbus_method_invocation_return_value(invocation, NULL);
809 |
810 | return;
811 | }
812 | else
813 | if (g_strcmp0(method_name, "focus_view") == 0)
814 | {
815 | uint view_id;
816 | uint action;
817 | g_variant_get(parameters, "(uu)", &view_id, &action);
818 |
819 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
820 | idle_call->run_once([=] ()
821 | {
822 | wayfire_view view = get_view_from_view_id(view_id);
823 | if (!check_view_toplevel(view)) {
824 | delete idle_call;
825 |
826 | return;
827 | }
828 |
829 | if (action == 0) {
830 | view->set_activated(false);
831 | }
832 |
833 | else
834 | if (action == 1)
835 | {
836 | view->set_activated(true);
837 | view->focus_request();
838 | }
839 |
840 | delete idle_call;
841 | });
842 | g_dbus_method_invocation_return_value(invocation, NULL);
843 |
844 | return;
845 | }
846 | else
847 | if (g_strcmp0(method_name, "fullscreen_view") == 0)
848 | {
849 | uint view_id;
850 | uint action;
851 | g_variant_get(parameters, "(uu)", &view_id, &action);
852 |
853 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
854 | idle_call->run_once([=] ()
855 | {
856 | wayfire_view view = get_view_from_view_id(view_id);
857 | if (!check_view_toplevel(view)) {
858 | delete idle_call;
859 |
860 | return;
861 | }
862 |
863 | wf::output_t* output = core.get_active_output();
864 |
865 | if (action == 0) {
866 | view->fullscreen_request(output, false);
867 | }
868 |
869 | else
870 | if (action == 1)
871 | {
872 | view->fullscreen_request(output, true);
873 | }
874 |
875 | else
876 | if (action == 2)
877 | {
878 | view->fullscreen_request(output, !view->fullscreen);
879 | }
880 |
881 | delete idle_call;
882 | });
883 | g_dbus_method_invocation_return_value(invocation, NULL);
884 |
885 | return;
886 | }
887 | else
888 | if (g_strcmp0(method_name, "close_view") == 0)
889 | {
890 | uint view_id;
891 | g_variant_get(parameters, "(u)", &view_id);
892 |
893 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
894 | idle_call->run_once([=] ()
895 | {
896 | wayfire_view view = get_view_from_view_id(view_id);
897 |
898 | if (check_view_toplevel(view)) {
899 | view->close();
900 | }
901 |
902 | delete idle_call;
903 | });
904 | g_dbus_method_invocation_return_value(invocation, NULL);
905 |
906 | return;
907 | }
908 | else
909 | if (g_strcmp0(method_name, "change_view_minimize_hint") == 0)
910 | {
911 | uint view_id;
912 | int x, y, width, height;
913 |
914 | g_variant_get(parameters, "(uiiii)", &view_id, &x, &y, &width, &height);
915 |
916 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
917 | idle_call->run_once([=] ()
918 | {
919 | wayfire_view view = get_view_from_view_id(view_id);
920 | if (!check_view_toplevel(view)) {
921 | delete idle_call;
922 |
923 | return;
924 | }
925 |
926 | view->set_minimize_hint({x, y, width, height});
927 | delete idle_call;
928 | });
929 |
930 | g_dbus_method_invocation_return_value(invocation, nullptr);
931 |
932 | return;
933 | }
934 |
935 | else
936 | if (g_strcmp0(method_name, "change_output_view") == 0)
937 | {
938 | uint view_id;
939 | uint output_id;
940 |
941 | g_variant_get(parameters, "(uu)", &view_id, &output_id);
942 |
943 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
944 | idle_call->run_once([=] ()
945 | {
946 | wayfire_view view = get_view_from_view_id(view_id);
947 | if (!check_view_toplevel(view)) {
948 | delete idle_call;
949 |
950 | return;
951 | }
952 |
953 | wf::output_t* output = get_output_from_output_id(output_id);
954 | if (output) {
955 | core.move_view_to_output(view, output, TRUE);
956 | }
957 |
958 | delete idle_call;
959 | });
960 | g_dbus_method_invocation_return_value(invocation, NULL);
961 |
962 | return;
963 | }
964 | else
965 | if (g_strcmp0(method_name, "change_workspace_view") == 0)
966 | {
967 | uint view_id;
968 | int new_workspace_x;
969 | int new_workspace_y;
970 |
971 | g_variant_get(parameters, "(uii)", &view_id, &new_workspace_x,
972 | &new_workspace_y);
973 |
974 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
975 | idle_call->run_once([=] ()
976 | {
977 | wayfire_view view = get_view_from_view_id(view_id);
978 | if (!check_view_toplevel(view)) {
979 | delete idle_call;
980 |
981 | return;
982 | }
983 |
984 | wf::point_t new_workspace_coord = {new_workspace_x, new_workspace_y};
985 | wf::output_t* output = view->get_output();
986 | output->workspace->move_to_workspace(view, new_workspace_coord);
987 | delete idle_call;
988 | });
989 |
990 | g_dbus_method_invocation_return_value(invocation, NULL);
991 |
992 | return;
993 | }
994 | else
995 | if (g_strcmp0(method_name, "change_workspace_output") == 0)
996 | {
997 | uint output_id;
998 | int new_workspace_x;
999 | int new_workspace_y;
1000 |
1001 | g_variant_get(parameters, "(uii)", &output_id, &new_workspace_x,
1002 | &new_workspace_y);
1003 |
1004 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
1005 | idle_call->run_once([=] ()
1006 | {
1007 | wf::output_t* output = get_output_from_output_id(output_id);
1008 |
1009 | if (output) {
1010 | wf::point_t new_workspace_coord;
1011 | new_workspace_coord = {new_workspace_x, new_workspace_y};
1012 | output->workspace->request_workspace(new_workspace_coord);
1013 | // Provides animation if available
1014 | }
1015 |
1016 | delete idle_call;
1017 | });
1018 | g_dbus_method_invocation_return_value(invocation, NULL);
1019 |
1020 | return;
1021 | }
1022 | else
1023 | if (g_strcmp0(method_name, "change_workspace_all_outputs") == 0)
1024 | {
1025 | int new_workspace_x;
1026 | int new_workspace_y;
1027 |
1028 | g_variant_get(parameters, "(ii)", &new_workspace_x, &new_workspace_y);
1029 |
1030 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
1031 | idle_call->run_once([=] ()
1032 | {
1033 | wf::point_t new_workspace_coord;
1034 | new_workspace_coord = {new_workspace_x, new_workspace_y};
1035 |
1036 | for (wf::output_t* output : wf_outputs)
1037 | {
1038 | if (output) {
1039 | output->workspace->request_workspace(new_workspace_coord);
1040 | }
1041 | }
1042 |
1043 | delete idle_call;
1044 | });
1045 | g_dbus_method_invocation_return_value(invocation, NULL);
1046 |
1047 | return;
1048 | }
1049 | else
1050 | if (g_strcmp0(method_name, "show_desktop") == 0)
1051 | {
1052 | // g_variant_ref(parameters);
1053 | // wl_event_loop_add_idle(core.ev_loop,
1054 | // local_thread_show_desktop,
1055 | // static_cast (parameters));
1056 | g_dbus_method_invocation_return_value(invocation, NULL);
1057 |
1058 | return;
1059 | }
1060 | else
1061 | if (g_strcmp0(method_name, "scale") == 0)
1062 | {
1063 | gboolean all_workspaces = FALSE;
1064 | gchar* app_id = nullptr;
1065 | g_variant_get(parameters, "(bs)", &all_workspaces, &app_id);
1066 |
1067 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
1068 | idle_call->run_once(
1069 | [all_workspaces, app_id = std::string(app_id), idle_call] ()
1070 | {
1071 | wf::output_t* output = core.get_active_output();
1072 | auto filter = dbus_scale_filter::get(output);
1073 | filter->set_filter(std::move(app_id));
1074 |
1075 | if (output->is_plugin_active("scale")) {
1076 | output->emit_signal("scale-update", nullptr);
1077 | }
1078 | else
1079 | {
1080 | wf::activator_data_t adata;
1081 | adata.source = wf::activator_source_t::PLUGIN;
1082 | output->call_plugin(
1083 | all_workspaces ? "scale/toggle_all" : "scale/toggle", adata);
1084 | }
1085 |
1086 | delete idle_call;
1087 | });
1088 |
1089 | g_dbus_method_invocation_return_value(invocation, nullptr);
1090 | }
1091 |
1092 | /*************** Non-reffing actions at end ****************/
1093 | else
1094 | if (g_strcmp0(method_name, "enable_property_mode") == 0)
1095 | {
1096 | bool enable;
1097 | g_variant_get(parameters, "(b)", &enable);
1098 | find_view_under_action = enable;
1099 |
1100 | /**
1101 | * Eventually store current cursor
1102 | * and restore it if different from
1103 | * "default"
1104 | */
1105 | if (enable) {
1106 | for (wf::output_t* output : wf_outputs)
1107 | {
1108 | if (!output->activate_plugin(grab_interfaces[output])) {
1109 | continue;
1110 | }
1111 |
1112 | grab_interfaces[output]->grab();
1113 | }
1114 |
1115 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
1116 | idle_call->run_once([core, idle_call] ()
1117 | {
1118 | core.set_cursor("crosshair");
1119 | delete idle_call;
1120 | });
1121 | }
1122 | else
1123 | {
1124 | for (wf::output_t* output : wf_outputs)
1125 | {
1126 | output->deactivate_plugin(grab_interfaces[output]);
1127 | grab_interfaces[output]->ungrab();
1128 | }
1129 |
1130 | wf::wl_idle_call* idle_call = new wf::wl_idle_call;
1131 | idle_call->run_once([=] ()
1132 | {
1133 | core.set_cursor("default");
1134 | delete idle_call;
1135 | });
1136 | }
1137 |
1138 | g_dbus_method_invocation_return_value(invocation, nullptr);
1139 |
1140 | return;
1141 | }
1142 | else
1143 | if (g_strcmp0(method_name, "query_cursor_position") == 0)
1144 | {
1145 | /*
1146 | * It uses the output relative cursor position
1147 | * as expected by minimize rect and popup positions
1148 | */
1149 | wf::pointf_t cursor_position;
1150 | GVariant* value;
1151 |
1152 | cursor_position = core.get_active_output()->get_cursor_position();
1153 | value = g_variant_new("(dd)", cursor_position.x, cursor_position.y);
1154 | g_dbus_method_invocation_return_value(invocation, value);
1155 |
1156 | return;
1157 | }
1158 | else
1159 | if (g_strcmp0(method_name, "query_output_ids") == 0)
1160 | {
1161 | GVariantBuilder builder;
1162 | GVariant* value;
1163 |
1164 | g_variant_builder_init(&builder, G_VARIANT_TYPE("au"));
1165 |
1166 | for (wf::output_t* wf_output : wf_outputs)
1167 | {
1168 | g_variant_builder_add(&builder, "u", wf_output->get_id());
1169 | }
1170 |
1171 | value = g_variant_new("(au)", &builder);
1172 | g_dbus_method_invocation_return_value(invocation, value);
1173 |
1174 | return;
1175 | }
1176 | else
1177 | if (g_strcmp0(method_name, "query_active_output") == 0)
1178 | {
1179 | uint output_id;
1180 | output_id = core.get_active_output()->get_id();
1181 | g_dbus_method_invocation_return_value(invocation,
1182 | g_variant_new("(u)", output_id));
1183 |
1184 | return;
1185 | }
1186 | else
1187 | if (g_strcmp0(method_name, "query_view_vector_ids") == 0)
1188 | {
1189 | std::vector> view_vector;
1190 | GVariantBuilder builder;
1191 | GVariant* value;
1192 |
1193 | view_vector = core.get_all_views();
1194 | g_variant_builder_init(&builder, G_VARIANT_TYPE("au"));
1195 | for (auto it = begin(view_vector); it != end(view_vector); ++it)
1196 | {
1197 | g_variant_builder_add(&builder, "u", it->get()->get_id());
1198 | }
1199 |
1200 | value = g_variant_new("(au)", &builder);
1201 | g_dbus_method_invocation_return_value(invocation, value);
1202 |
1203 | return;
1204 | }
1205 | else
1206 | if (g_strcmp0(method_name, "query_view_vector_taskman_ids") == 0)
1207 | {
1208 | std::vector> view_vector =
1209 | core.get_all_views();
1210 | GVariantBuilder builder;
1211 | GVariant* value;
1212 |
1213 | g_variant_builder_init(&builder, G_VARIANT_TYPE("au"));
1214 | for (auto it = begin(view_vector); it != end(view_vector); ++it)
1215 | {
1216 | if ((it->get()->role != wf::VIEW_ROLE_TOPLEVEL) ||
1217 | !it->get()->is_mapped()) {
1218 | continue;
1219 | }
1220 | else
1221 | {
1222 | g_variant_builder_add(&builder, "u", it->get()->get_id());
1223 | }
1224 | }
1225 |
1226 | value = g_variant_new("(au)", &builder);
1227 | g_dbus_method_invocation_return_value(invocation, value);
1228 |
1229 | return;
1230 | }
1231 | /*************** Output Properties ****************/
1232 | else
1233 | if (g_strcmp0(method_name, "query_output_name") == 0)
1234 | {
1235 | uint output_id;
1236 | gchar* response = "nullptr";
1237 | g_variant_get(parameters, "(u)", &output_id);
1238 | wf::output_t* wf_output = get_output_from_output_id(output_id);
1239 |
1240 | if (wf_output != nullptr) {
1241 | response = g_strdup_printf(wf_output->to_string().c_str());
1242 | }
1243 |
1244 | g_dbus_method_invocation_return_value(invocation,
1245 | g_variant_new("(s)", response));
1246 | if (wf_output != nullptr) {
1247 | g_free(response);
1248 | }
1249 |
1250 | return;
1251 | }
1252 | else
1253 | if (g_strcmp0(method_name, "query_output_manufacturer") == 0)
1254 | {
1255 | uint output_id;
1256 | gchar* response = "nullptr";
1257 | wf::output_t* output;
1258 | wlr_output* wlr_output = nullptr;
1259 |
1260 | g_variant_get(parameters, "(u)", &output_id);
1261 | output = get_output_from_output_id(output_id);
1262 | if (output) {
1263 | wlr_output = output->handle;
1264 |
1265 | if (wlr_output != nullptr) {
1266 | response = g_strdup_printf(wlr_output->make);
1267 | }
1268 | }
1269 |
1270 | g_dbus_method_invocation_return_value(invocation,
1271 | g_variant_new("(s)", response));
1272 | if (wlr_output != nullptr) {
1273 | g_free(response);
1274 | }
1275 |
1276 | return;
1277 | }
1278 | else
1279 | if (g_strcmp0(method_name, "query_output_model") == 0)
1280 | {
1281 | uint output_id;
1282 | gchar* response = "nullptr";
1283 | wf::output_t* output;
1284 | wlr_output* wlr_output = nullptr;
1285 |
1286 | g_variant_get(parameters, "(u)", &output_id);
1287 | output = get_output_from_output_id(output_id);
1288 | if (output) {
1289 | wlr_output = output->handle;
1290 |
1291 | if (wlr_output != nullptr) {
1292 | response = g_strdup_printf(wlr_output->model);
1293 | }
1294 | }
1295 |
1296 | g_dbus_method_invocation_return_value(invocation,
1297 | g_variant_new("(s)", response));
1298 | if (wlr_output != nullptr) {
1299 | g_free(response);
1300 | }
1301 |
1302 | return;
1303 | }
1304 | else
1305 | if (g_strcmp0(method_name, "query_output_serial") == 0)
1306 | {
1307 | uint output_id;
1308 | gchar* response = "nullptr";
1309 | wf::output_t* wf_output;
1310 | wlr_output* wlr_output = nullptr;
1311 |
1312 | g_variant_get(parameters, "(u)", &output_id);
1313 | wf_output = get_output_from_output_id(output_id);
1314 | wlr_output = wf_output->handle;
1315 |
1316 | if (wlr_output != nullptr) {
1317 | response = g_strdup_printf(wlr_output->serial);
1318 | }
1319 |
1320 | g_dbus_method_invocation_return_value(invocation,
1321 | g_variant_new("(s)", response));
1322 | if (wlr_output != nullptr) {
1323 | g_free(response);
1324 | }
1325 |
1326 | return;
1327 | }
1328 | else
1329 | if (g_strcmp0(method_name, "query_output_workspace") == 0)
1330 | {
1331 | uint output_id;
1332 | uint horizontal_workspace = 0;
1333 | uint vertical_workspace = 0;
1334 | wf::output_t* wf_output;
1335 | wf::point_t ws;
1336 |
1337 | g_variant_get(parameters, "(u)", &output_id);
1338 | wf_output = get_output_from_output_id(output_id);
1339 | if (wf_output) {
1340 | ws = wf_output->workspace->get_current_workspace();
1341 | horizontal_workspace = ws.x;
1342 | vertical_workspace = ws.y;
1343 | }
1344 |
1345 | g_dbus_method_invocation_return_value(
1346 | invocation,
1347 | g_variant_new("(uu)", horizontal_workspace, vertical_workspace));
1348 |
1349 | return;
1350 | }
1351 | else
1352 | if (g_strcmp0(method_name, "query_workspace_grid_size") == 0)
1353 | {
1354 | wf::dimensions_t workspaces;
1355 | workspaces = core.get_active_output()->workspace->get_workspace_grid_size();
1356 |
1357 | g_dbus_method_invocation_return_value(
1358 | invocation, g_variant_new("(ii)", workspaces.width, workspaces.height));
1359 |
1360 | return;
1361 | }
1362 | /*************** View Properties ****************/
1363 | else
1364 | if (g_strcmp0(method_name, "query_view_above_view") == 0)
1365 | {
1366 | uint view_id;
1367 | g_variant_get(parameters, "(u)", &view_id);
1368 |
1369 | wayfire_view view = get_view_from_view_id(view_id);
1370 | wf::output_t* output;
1371 | int view_above = -1;
1372 | std::vector workspace_views;
1373 |
1374 | if (!check_view_toplevel(view)) {
1375 | g_dbus_method_invocation_return_value(invocation,
1376 | g_variant_new("(i)", view_above));
1377 |
1378 | return;
1379 | }
1380 |
1381 | while (view->parent)
1382 | {
1383 | view = view->parent;
1384 | }
1385 |
1386 | if (!check_view_toplevel(view)) {
1387 | g_dbus_method_invocation_return_value(
1388 | invocation, g_variant_new("(i)", view_above));
1389 |
1390 | return;
1391 | }
1392 |
1393 | output = view->get_output();
1394 | if (!output) {
1395 | g_dbus_method_invocation_return_value(invocation,
1396 | g_variant_new("(i)", view_above));
1397 |
1398 | return;
1399 | }
1400 |
1401 | workspace_views =
1402 | output->workspace->get_views_in_layer(wf::MIDDLE_LAYERS);
1403 |
1404 | for (int i = 0; i < workspace_views.size() - 1; i++)
1405 | {
1406 | wayfire_view v = workspace_views[i];
1407 | if (!check_view_toplevel(v)) {
1408 | continue;
1409 | }
1410 |
1411 | if (v == view) {
1412 | if (i != 0) {
1413 | if (check_view_toplevel(workspace_views[i - 1])) {
1414 | view_above = workspace_views[i - 1]->get_id();
1415 | }
1416 |
1417 | break;
1418 | }
1419 | }
1420 | }
1421 |
1422 | g_dbus_method_invocation_return_value(invocation,
1423 | g_variant_new("(i)", view_above));
1424 |
1425 | return;
1426 | }
1427 | else
1428 | if (g_strcmp0(method_name, "query_view_below_view") == 0)
1429 | {
1430 | uint view_id;
1431 | g_variant_get(parameters, "(u)", &view_id);
1432 |
1433 | wayfire_view view = get_view_from_view_id(view_id);
1434 | wf::output_t* output;
1435 | int view_below = -1;
1436 | std::vector workspace_views;
1437 |
1438 | if (!check_view_toplevel(view)) {
1439 | g_dbus_method_invocation_return_value(invocation,
1440 | g_variant_new("(i)", view_below));
1441 |
1442 | return;
1443 | }
1444 |
1445 | while (view->parent)
1446 | {
1447 | view = view->parent;
1448 | }
1449 |
1450 | if (!check_view_toplevel(view)) {
1451 | g_dbus_method_invocation_return_value(
1452 | invocation, g_variant_new("(i)", view_below));
1453 |
1454 | return;
1455 | }
1456 |
1457 | output = view->get_output();
1458 | if (!output) {
1459 | g_dbus_method_invocation_return_value(invocation,
1460 | g_variant_new("(i)", view_below));
1461 |
1462 | return;
1463 | }
1464 |
1465 | workspace_views =
1466 | output->workspace->get_views_in_layer(wf::MIDDLE_LAYERS);
1467 |
1468 | for (int i = 0; i < workspace_views.size() - 1; i++)
1469 | {
1470 | wayfire_view v = workspace_views[i];
1471 | if (!check_view_toplevel(v)) {
1472 | continue;
1473 | }
1474 |
1475 | if (v == view) {
1476 | if (i != workspace_views.size() - 1) {
1477 | if (check_view_toplevel(workspace_views[i + 1])) {
1478 | view_below = workspace_views[i + 1]->get_id();
1479 | }
1480 |
1481 | break;
1482 | }
1483 | }
1484 |
1485 | // if (view_below != -1)
1486 | // {
1487 | // g_warning("Below %s is %s", view->get_title().c_str(),
1488 | // get_view_from_view_id(view_below)->get_title().c_str());
1489 | // }
1490 | // else
1491 | // {
1492 | // g_warning("No view below %s", view->get_title().c_str());
1493 | // }
1494 | }
1495 |
1496 | g_dbus_method_invocation_return_value(invocation,
1497 | g_variant_new("(i)", view_below));
1498 |
1499 | return;
1500 | }
1501 | else
1502 | if (g_strcmp0(method_name, "query_view_app_id") == 0)
1503 | {
1504 | uint view_id;
1505 | gchar* response = "nullptr";
1506 | wayfire_view view;
1507 |
1508 | g_variant_get(parameters, "(u)", &view_id);
1509 | view = get_view_from_view_id(view_id);
1510 |
1511 | if (!check_view_toplevel(view)) {
1512 | g_dbus_method_invocation_return_value(invocation,
1513 | g_variant_new("(s)", response));
1514 |
1515 | return;
1516 | }
1517 |
1518 | response = g_strdup(view->get_app_id().c_str());
1519 | g_dbus_method_invocation_return_value(invocation,
1520 | g_variant_new("(s)", response));
1521 | g_free(response);
1522 |
1523 | return;
1524 | }
1525 | else
1526 | if (g_strcmp0(method_name, "query_view_app_id_gtk_shell") == 0)
1527 | {
1528 | uint view_id;
1529 | gchar* response = "nullptr";
1530 | wayfire_view view;
1531 |
1532 | g_variant_get(parameters, "(u)", &view_id);
1533 | view = get_view_from_view_id(view_id);
1534 |
1535 | if (!check_view_toplevel(view)) {
1536 | g_dbus_method_invocation_return_value(invocation,
1537 | g_variant_new("(s)", response));
1538 |
1539 | return;
1540 | }
1541 |
1542 | response = g_strdup(get_gtk_shell_app_id(view).c_str());
1543 | g_dbus_method_invocation_return_value(invocation,
1544 | g_variant_new("(s)", response));
1545 | g_free(response);
1546 |
1547 | return;
1548 | }
1549 | else
1550 | if (g_strcmp0(method_name, "query_view_app_id_xwayland_net_wm_name") ==
1551 | 0)
1552 | {
1553 | uint view_id;
1554 | gchar* response = "nullptr";
1555 | wayfire_view view;
1556 | bool free_response = false;
1557 |
1558 | g_variant_get(parameters, "(u)", &view_id);
1559 | view = get_view_from_view_id(view_id);
1560 |
1561 | if (view) {
1562 | auto wlr_surf = view->get_wlr_surface();
1563 | if (!wlr_surf) {
1564 | g_dbus_method_invocation_return_value(invocation,
1565 | g_variant_new("(s)", response));
1566 |
1567 | return;
1568 | }
1569 |
1570 | if (wlr_surface_is_xwayland_surface(wlr_surf)) {
1571 | struct wlr_xwayland_surface* xsurf;
1572 | xsurf = wlr_xwayland_surface_from_wlr_surface(wlr_surf);
1573 | if (!xsurf) {
1574 | g_dbus_method_invocation_return_value(invocation,
1575 | g_variant_new("(s)", response));
1576 |
1577 | return;
1578 | }
1579 |
1580 | g_assert(xsurf != NULL);
1581 | std::string wm_name_app_id = nonull(xsurf->instance);
1582 | response = g_strdup_printf(wm_name_app_id.c_str());
1583 | free_response = true;
1584 | }
1585 | }
1586 |
1587 | if (free_response) {
1588 | g_free(response);
1589 | }
1590 |
1591 | g_dbus_method_invocation_return_value(invocation,
1592 | g_variant_new("(s)", response));
1593 |
1594 | return;
1595 | }
1596 | else
1597 | if (g_strcmp0(method_name, "query_view_title") == 0)
1598 | {
1599 | uint view_id;
1600 | gchar* response = "nullptr";
1601 | wayfire_view view;
1602 |
1603 | g_variant_get(parameters, "(u)", &view_id);
1604 | view = get_view_from_view_id(view_id);
1605 |
1606 | if (!check_view_toplevel(view)) {
1607 | g_dbus_method_invocation_return_value(invocation,
1608 | g_variant_new("(s)", response));
1609 |
1610 | return;
1611 | }
1612 |
1613 | response = g_strdup_printf(view->get_title().c_str());
1614 | g_dbus_method_invocation_return_value(invocation,
1615 | g_variant_new("(s)", response));
1616 | g_free(response);
1617 |
1618 | return;
1619 | }
1620 | else
1621 | if (g_strcmp0(method_name, "query_view_attention") == 0)
1622 | {
1623 | uint view_id;
1624 | bool attention = false;
1625 | wayfire_view view;
1626 |
1627 | g_variant_get(parameters, "(u)", &view_id);
1628 | view = get_view_from_view_id(view_id);
1629 | if (!check_view_toplevel(view)) {
1630 | return;
1631 | }
1632 |
1633 | if (view->has_data("view-demands-attention")) {
1634 | attention = true;
1635 | }
1636 |
1637 | g_dbus_method_invocation_return_value(invocation,
1638 | g_variant_new("(b)", attention));
1639 |
1640 | return;
1641 | }
1642 | else
1643 | if (g_strcmp0(method_name, "query_xwayland_display") == 0)
1644 | {
1645 | const char* xdisplay = core.get_xwayland_display().c_str();
1646 |
1647 | g_dbus_method_invocation_return_value(invocation,
1648 | g_variant_new("(s)", xdisplay));
1649 |
1650 | return;
1651 | }
1652 | else
1653 | if (g_strcmp0(method_name, "query_view_xwayland_wid") == 0)
1654 | {
1655 | uint view_id;
1656 | wayfire_view view;
1657 |
1658 | g_variant_get(parameters, "(u)", &view_id);
1659 | view = get_view_from_view_id(view_id);
1660 |
1661 | if (!view) {
1662 | g_dbus_method_invocation_return_value(invocation,
1663 | g_variant_new("(u)", 0));
1664 |
1665 | return;
1666 | }
1667 |
1668 | if (xwayland_enabled == 1) {
1669 | auto main_wlr_surface = view->get_main_surface()->get_wlr_surface();
1670 | if (!main_wlr_surface) {
1671 | g_dbus_method_invocation_return_value(invocation,
1672 | g_variant_new("(u)", 0));
1673 |
1674 | return;
1675 | }
1676 |
1677 | if (wlr_surface_is_xwayland_surface(main_wlr_surface)) {
1678 | #ifdef DBUS_PLUGIN_DEBUG
1679 | LOG(wf::log::LOG_LEVEL_DEBUG, "xwayland is the surface type.");
1680 | #endif
1681 | struct wlr_xwayland_surface* main_xsurf;
1682 | main_xsurf = wlr_xwayland_surface_from_wlr_surface(main_wlr_surface);
1683 | g_dbus_method_invocation_return_value(
1684 | invocation, g_variant_new("(u)", main_xsurf->window_id));
1685 |
1686 | return;
1687 | }
1688 | }
1689 |
1690 | g_dbus_method_invocation_return_value(invocation, g_variant_new("(u)", 0));
1691 |
1692 | return;
1693 | }
1694 | else
1695 | if (g_strcmp0(method_name, "query_view_xwayland_atom_cardinal") == 0)
1696 | {
1697 | uint view_id;
1698 | uint atom_value_cardinal = 0;
1699 | gchar* atom_name;
1700 | wayfire_view view;
1701 |
1702 | g_variant_get(parameters, "(us)", &view_id, &atom_name);
1703 | view = get_view_from_view_id(view_id);
1704 |
1705 | if (!view) {
1706 | g_dbus_method_invocation_return_value(invocation,
1707 | g_variant_new("(u)", 0));
1708 |
1709 | return;
1710 | }
1711 |
1712 | auto main_wlr_surface = view->get_main_surface()->get_wlr_surface();
1713 | if (!main_wlr_surface) {
1714 | g_dbus_method_invocation_return_value(invocation,
1715 | g_variant_new("(u)", 0));
1716 |
1717 | return;
1718 | }
1719 |
1720 | if ((xwayland_enabled != 1) ||
1721 | !wlr_surface_is_xwayland_surface(main_wlr_surface)) {
1722 | g_dbus_method_invocation_return_value(invocation,
1723 | g_variant_new("(u)", 0));
1724 |
1725 | return;
1726 | }
1727 |
1728 | struct wlr_xwayland_surface* main_xsurf;
1729 | main_xsurf = wlr_xwayland_surface_from_wlr_surface(main_wlr_surface);
1730 |
1731 | const char* xdisplay = core.get_xwayland_display().c_str();
1732 | int screen;
1733 | xcb_connection_t* conn = xcb_connect(xdisplay, &screen);
1734 | xcb_intern_atom_cookie_t atom_cookie;
1735 | xcb_atom_t atom;
1736 | xcb_intern_atom_reply_t* reply;
1737 | atom_cookie = xcb_intern_atom(conn, 0, strlen(atom_name), atom_name);
1738 | reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
1739 | if (reply != NULL) {
1740 | atom = reply->atom;
1741 | free(reply);
1742 | }
1743 | else
1744 | {
1745 | #ifdef DBUS_PLUGIN_DEBUG
1746 | LOG(wf::log::LOG_LEVEL_DEBUG, "reply for querying the atom is empty.");
1747 | #endif
1748 | g_dbus_method_invocation_return_value(
1749 | invocation, g_variant_new("(u)", atom_value_cardinal));
1750 |
1751 | return;
1752 | }
1753 |
1754 | xcb_get_property_cookie_t reply_cookie;
1755 | xcb_get_property_reply_t* reply_value;
1756 | reply_cookie = xcb_get_property(conn, 0, main_xsurf->window_id, atom,
1757 | XCB_ATOM_ANY, 0, 2048);
1758 | reply_value = xcb_get_property_reply(conn, reply_cookie, NULL);
1759 | xcb_disconnect(conn);
1760 |
1761 | if (reply_value->type == XCB_ATOM_CARDINAL) {
1762 | uint* uvalue = (uint*)xcb_get_property_value(reply_value);
1763 | atom_value_cardinal = *uvalue;
1764 | #ifdef DBUS_PLUGIN_DEBUG
1765 | LOG(wf::log::LOG_LEVEL_DEBUG, "value to uint.", atom_value_cardinal);
1766 | #endif
1767 | }
1768 |
1769 | #ifdef DBUS_PLUGIN_DEBUG
1770 | else
1771 | {
1772 | LOG(wf::log::LOG_LEVEL_DEBUG, "requested value is not a cardinal");
1773 | }
1774 | #endif
1775 |
1776 | g_dbus_method_invocation_return_value(
1777 | invocation, g_variant_new("(u)", atom_value_cardinal));
1778 |
1779 | return;
1780 | }
1781 | else
1782 | if (g_strcmp0(method_name, "query_view_xwayland_atom_string") == 0)
1783 | {
1784 | uint view_id;
1785 | gchar* atom_name;
1786 | gchar* atom_value_string = "No atom value received.";
1787 |
1788 | g_variant_get(parameters, "(us)", &view_id, &atom_name);
1789 |
1790 | wayfire_view view = get_view_from_view_id(view_id);
1791 |
1792 | if (!view) {
1793 | g_dbus_method_invocation_return_value(
1794 | invocation, g_variant_new("(s)", "View not found."));
1795 |
1796 | return;
1797 | }
1798 |
1799 | auto main_wlr_surface = view->get_main_surface()->get_wlr_surface();
1800 |
1801 | if (!main_wlr_surface) {
1802 | g_dbus_method_invocation_return_value(
1803 | invocation, g_variant_new("(s)", "main_wlr_surface not found."));
1804 |
1805 | return;
1806 | }
1807 |
1808 | if ((xwayland_enabled != 1) ||
1809 | !wlr_surface_is_xwayland_surface(main_wlr_surface)) {
1810 | g_dbus_method_invocation_return_value(
1811 | invocation, g_variant_new("(s)", "Not an xwayland surface."));
1812 |
1813 | return;
1814 | }
1815 |
1816 | struct wlr_xwayland_surface* main_xsurf;
1817 |
1818 | main_xsurf = wlr_xwayland_surface_from_wlr_surface(main_wlr_surface);
1819 |
1820 | const char* xdisplay = core.get_xwayland_display().c_str();
1821 | int screen;
1822 | xcb_connection_t* conn = xcb_connect(xdisplay, &screen);
1823 | xcb_intern_atom_cookie_t atom_cookie;
1824 | xcb_atom_t atom;
1825 | xcb_intern_atom_reply_t* reply;
1826 | atom_cookie = xcb_intern_atom(conn, 0, strlen(atom_name), atom_name);
1827 | reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
1828 | if (reply != NULL) {
1829 | atom = reply->atom;
1830 | free(reply);
1831 | }
1832 | else
1833 | {
1834 | g_dbus_method_invocation_return_value(
1835 | invocation,
1836 | g_variant_new("(s)", "reply for querying the atom is empty."));
1837 |
1838 | return;
1839 | }
1840 |
1841 | xcb_get_property_cookie_t reply_cookie = xcb_get_property(
1842 | conn, 0, main_xsurf->window_id, atom, XCB_ATOM_ANY, 0, 2048);
1843 | xcb_get_property_reply_t* reply_value =
1844 | xcb_get_property_reply(conn, reply_cookie, NULL);
1845 |
1846 | char* value = static_cast (xcb_get_property_value(reply_value));
1847 |
1848 | xcb_disconnect(conn);
1849 |
1850 | if (reply_value->type != XCB_ATOM_CARDINAL) {
1851 | atom_value_string = value;
1852 | #ifdef DBUS_PLUGIN_DEBUG
1853 | LOG(wf::log::LOG_LEVEL_DEBUG, "value to char.", atom_value_string);
1854 | #endif
1855 | g_dbus_method_invocation_return_value(
1856 | invocation, g_variant_new("(s)", atom_value_string));
1857 |
1858 | return;
1859 | }
1860 | else
1861 | {
1862 | g_dbus_method_invocation_return_value(
1863 | invocation,
1864 | g_variant_new("(s)", "XCB_ATOM_CARDINAL type requested."));
1865 |
1866 | return;
1867 | }
1868 | }
1869 | else
1870 | if (g_strcmp0(method_name, "query_view_credentials") == 0)
1871 | {
1872 | uint view_id;
1873 | pid_t pid = 0;
1874 | uid_t uid = 0;
1875 | gid_t gid = 0;
1876 | wayfire_view view;
1877 |
1878 | g_variant_get(parameters, "(u)", &view_id);
1879 | view = get_view_from_view_id(view_id);
1880 |
1881 | if (!view) {
1882 | g_dbus_method_invocation_return_value(invocation,
1883 | g_variant_new("(iuu)", 0, 0, 0));
1884 |
1885 | return;
1886 | }
1887 |
1888 | if (xwayland_enabled == 1) {
1889 | auto main_surface = view->get_main_surface()->get_wlr_surface();
1890 | if (!main_surface) {
1891 | g_dbus_method_invocation_return_value(invocation,
1892 | g_variant_new("(iuu)", 0, 0, 0));
1893 |
1894 | return;
1895 | }
1896 |
1897 | if (wlr_surface_is_xwayland_surface(main_surface)) {
1898 | struct wlr_xwayland_surface* main_xsurf;
1899 | xcb_res_client_id_spec_t spec = {0};
1900 | xcb_generic_error_t* err = NULL;
1901 | xcb_res_query_client_ids_cookie_t cookie;
1902 | xcb_res_query_client_ids_reply_t* reply;
1903 | int screen;
1904 |
1905 | const char* xdisplay = core.get_xwayland_display().c_str();
1906 | xcb_connection_t* conn = xcb_connect(xdisplay, &screen);
1907 |
1908 | main_xsurf = wlr_xwayland_surface_from_wlr_surface(main_surface);
1909 | spec.client = main_xsurf->window_id;
1910 | spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
1911 | cookie = xcb_res_query_client_ids(conn, 1, &spec);
1912 | reply = xcb_res_query_client_ids_reply(conn, cookie, &err);
1913 |
1914 | if (reply == NULL) {
1915 | #ifdef DBUS_PLUGIN_DEBUG
1916 | LOG(wf::log::LOG_LEVEL_DEBUG,
1917 | "could not get pid from xserver, empty reply");
1918 | #endif
1919 | }
1920 | else
1921 | {
1922 | xcb_res_client_id_value_iterator_t it;
1923 | it = xcb_res_query_client_ids_ids_iterator(reply);
1924 | for (; it.rem; xcb_res_client_id_value_next(&it))
1925 | {
1926 | spec = it.data->spec;
1927 | if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
1928 | pid = *xcb_res_client_id_value_value(it.data);
1929 | break;
1930 | }
1931 | }
1932 |
1933 | free(reply);
1934 | }
1935 |
1936 | xcb_disconnect(conn);
1937 |
1938 | if (pid != 0) {
1939 | LOG(wf::log::LOG_LEVEL_DEBUG,
1940 | "returning xwayland window credentials.");
1941 | g_dbus_method_invocation_return_value(
1942 | invocation, g_variant_new("(iuu)", pid, uid, gid));
1943 |
1944 | return;
1945 | }
1946 | }
1947 | }
1948 |
1949 | #ifdef DBUS_PLUGIN_DEBUG
1950 | LOG(wf::log::LOG_LEVEL_DEBUG, "returning standard credentials.");
1951 | #endif
1952 | wl_client_get_credentials(view->get_client(), &pid, &uid, &gid);
1953 | g_dbus_method_invocation_return_value(
1954 | invocation, g_variant_new("(iuu)", pid, uid, gid));
1955 |
1956 | return;
1957 | }
1958 | else
1959 | if (g_strcmp0(method_name, "query_view_above") == 0)
1960 | {
1961 | wayfire_view view;
1962 | uint view_id;
1963 | bool above;
1964 |
1965 | g_variant_get(parameters, "(u)", &view_id);
1966 | view = get_view_from_view_id(view_id);
1967 | above = false;
1968 |
1969 | if (view) {
1970 | if (view->has_data("wm-actions-above")) {
1971 | above = true;
1972 | }
1973 | }
1974 |
1975 | #ifdef DBUS_PLUGIN_DEBUG
1976 | else
1977 | {
1978 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_above no view");
1979 | }
1980 | #endif
1981 | g_dbus_method_invocation_return_value(invocation,
1982 | g_variant_new("(b)", above));
1983 |
1984 | return;
1985 | }
1986 | else
1987 | if (g_strcmp0(method_name, "query_view_maximized") == 0)
1988 | {
1989 | wayfire_view view;
1990 | uint view_id;
1991 | bool response = false;
1992 |
1993 | g_variant_get(parameters, "(u)", &view_id);
1994 | view = get_view_from_view_id(view_id);
1995 |
1996 | if (view) {
1997 | response = (view->tiled_edges == wf::TILED_EDGES_ALL);
1998 | }
1999 |
2000 | #ifdef DBUS_PLUGIN_DEBUG
2001 | else
2002 | {
2003 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_maximized no view");
2004 | }
2005 | #endif
2006 | g_dbus_method_invocation_return_value(invocation,
2007 | g_variant_new("(b)", response));
2008 |
2009 | return;
2010 | }
2011 |
2012 | else
2013 | if (g_strcmp0(method_name, "query_view_active") == 0)
2014 | {
2015 | wayfire_view view;
2016 | uint view_id;
2017 | bool response = false;
2018 |
2019 | g_variant_get(parameters, "(u)", &view_id);
2020 | view = get_view_from_view_id(view_id);
2021 |
2022 | if (view) {
2023 | response = view->activated;
2024 | }
2025 |
2026 | #ifdef DBUS_PLUGIN_DEBUG
2027 | else
2028 | {
2029 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_active no view");
2030 | }
2031 | #endif
2032 | g_dbus_method_invocation_return_value(invocation,
2033 | g_variant_new("(b)", response));
2034 |
2035 | return;
2036 | }
2037 |
2038 | else
2039 | if (g_strcmp0(method_name, "query_view_minimized") == 0)
2040 | {
2041 | wayfire_view view;
2042 | uint view_id;
2043 | bool response = false;
2044 |
2045 | g_variant_get(parameters, "(u)", &view_id);
2046 | view = get_view_from_view_id(view_id);
2047 |
2048 | if (view) {
2049 | response = view->minimized;
2050 | }
2051 |
2052 | #ifdef DBUS_PLUGIN_DEBUG
2053 | else
2054 | {
2055 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_minimized no view");
2056 | }
2057 | #endif
2058 | g_dbus_method_invocation_return_value(invocation,
2059 | g_variant_new("(b)", response));
2060 |
2061 | return;
2062 | }
2063 |
2064 | else
2065 | if (g_strcmp0(method_name, "query_view_fullscreen") == 0)
2066 | {
2067 | uint view_id;
2068 | bool response = false;
2069 | wayfire_view view;
2070 |
2071 | g_variant_get(parameters, "(u)", &view_id);
2072 | view = get_view_from_view_id(view_id);
2073 |
2074 | if (view) {
2075 | response = view->fullscreen;
2076 | }
2077 |
2078 | #ifdef DBUS_PLUGIN_DEBUG
2079 | else
2080 | {
2081 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_fullscreen no view");
2082 | }
2083 | #endif
2084 | g_dbus_method_invocation_return_value(invocation,
2085 | g_variant_new("(b)", response));
2086 |
2087 | return;
2088 | }
2089 | else
2090 | if (g_strcmp0(method_name, "query_view_output") == 0)
2091 | {
2092 | uint view_id;
2093 | uint output_id = 0;
2094 | wayfire_view view;
2095 |
2096 | g_variant_get(parameters, "(u)", &view_id);
2097 | view = get_view_from_view_id(view_id);
2098 |
2099 | if (view) {
2100 | if (view->get_output()) {
2101 | output_id = view->get_output()->get_id();
2102 | }
2103 |
2104 | #ifdef DBUS_PLUGIN_DEBUG
2105 |
2106 | else
2107 | {
2108 | g_warning("No output for view.");
2109 | }
2110 | #endif
2111 | }
2112 |
2113 | g_dbus_method_invocation_return_value(invocation,
2114 | g_variant_new("(u)", output_id));
2115 |
2116 | return;
2117 | }
2118 | else
2119 | if (g_strcmp0(method_name, "query_view_workspaces") == 0)
2120 | {
2121 | #ifdef DBUS_PLUGIN_DEBUG
2122 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_workspaces ");
2123 | #endif
2124 |
2125 | uint view_id;
2126 | double area;
2127 | GVariantBuilder builder;
2128 | GVariant* value;
2129 | wf::geometry_t workspace_relative_geometry;
2130 | wlr_box view_relative_geometry;
2131 | wf::geometry_t intersection;
2132 | wf::dimensions_t workspaces;
2133 | wf::output_t* output;
2134 |
2135 | g_variant_get(parameters, "(u)", &view_id);
2136 | wayfire_view view = get_view_from_view_id(view_id);
2137 |
2138 | if (!check_view_toplevel(view)) {
2139 | #ifdef DBUS_PLUGIN_DEBUG
2140 |
2141 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_workspaces no view");
2142 | #endif
2143 | g_dbus_method_invocation_return_value(invocation, NULL);
2144 |
2145 | return;
2146 | }
2147 |
2148 | workspaces = core.get_active_output()->workspace->get_workspace_grid_size();
2149 |
2150 | view_relative_geometry = view->get_bounding_box();
2151 | output = view->get_output();
2152 |
2153 | g_variant_builder_init(&builder, G_VARIANT_TYPE("a(ii)"));
2154 |
2155 | for (int horizontal_workspace = 0; horizontal_workspace < workspaces.width;
2156 | horizontal_workspace++)
2157 | {
2158 | for (int vertical_workspace = 0; vertical_workspace < workspaces.height;
2159 | vertical_workspace++)
2160 | {
2161 | wf::point_t ws = {horizontal_workspace, vertical_workspace};
2162 | if (output->workspace->view_visible_on(view, ws)) {
2163 | workspace_relative_geometry = output->render->get_ws_box(ws);
2164 | intersection = wf::geometry_intersection(view_relative_geometry,
2165 | workspace_relative_geometry);
2166 | area = 1.0 * intersection.width * intersection.height;
2167 | area /= 1.0 * view_relative_geometry.width *
2168 | view_relative_geometry.height;
2169 |
2170 | if (area > 0.1) {
2171 | g_variant_builder_add(&builder, "(ii)", horizontal_workspace,
2172 | vertical_workspace);
2173 | }
2174 | }
2175 | }
2176 | }
2177 |
2178 | value = g_variant_new("(a(ii))", &builder);
2179 | g_dbus_method_invocation_return_value(invocation, value);
2180 |
2181 | return;
2182 | }
2183 | else
2184 | if (g_strcmp0(method_name, "query_view_group_leader") == 0)
2185 | {
2186 | uint view_id;
2187 | uint group_leader_view_id;
2188 | wayfire_view view;
2189 |
2190 | g_variant_get(parameters, "(u)", &view_id);
2191 | group_leader_view_id = view_id;
2192 | view = get_view_from_view_id(view_id);
2193 |
2194 | if (view) {
2195 | while (view->parent)
2196 | {
2197 | view = view->parent;
2198 | }
2199 |
2200 | group_leader_view_id = view->get_id();
2201 | #ifdef DBUS_PLUGIN_DEBUG
2202 | LOG(wf::log::LOG_LEVEL_DEBUG, "query_view_group_leader found returning");
2203 | #endif
2204 | }
2205 |
2206 | g_dbus_method_invocation_return_value(
2207 | invocation, g_variant_new("(u)", group_leader_view_id));
2208 |
2209 | return;
2210 | }
2211 | else
2212 | if (g_strcmp0(method_name, "query_view_role") == 0)
2213 | {
2214 | uint view_id;
2215 | uint response = 0;
2216 | bool is_modal_dialog;
2217 | wayfire_view view;
2218 |
2219 | g_variant_get(parameters, "(u)", &view_id);
2220 | view = get_view_from_view_id(view_id);
2221 |
2222 | if (view) {
2223 | if (view->is_mapped()) {
2224 | is_modal_dialog = view->has_data("gtk-shell-modal");
2225 |
2226 | if ((view->role == wf::VIEW_ROLE_TOPLEVEL) && !is_modal_dialog) {
2227 | response = 1;
2228 | }
2229 |
2230 | else
2231 | if (view->role == wf::VIEW_ROLE_DESKTOP_ENVIRONMENT)
2232 | {
2233 | response = 2;
2234 | }
2235 |
2236 | else
2237 | if (view->role == wf::VIEW_ROLE_UNMANAGED)
2238 | {
2239 | response = 3;
2240 | }
2241 | }
2242 | }
2243 |
2244 | g_dbus_method_invocation_return_value(invocation,
2245 | g_variant_new("(u)", response));
2246 |
2247 | return;
2248 | }
2249 | else
2250 | if (g_strcmp0(method_name, "query_view_test_data") == 0)
2251 | {
2252 | uint view_id;
2253 | wayfire_view view;
2254 |
2255 | g_variant_get(parameters, "(u)", &view_id);
2256 | view = get_view_from_view_id(view_id);
2257 |
2258 | if (!check_view_toplevel(view))
2259 | {
2260 | g_dbus_method_invocation_return_value(invocation,
2261 | g_variant_new("(uu)", 0, 0));
2262 |
2263 | return;
2264 | }
2265 |
2266 | auto wlr_surf = view->get_wlr_surface();
2267 | if (!wlr_surf) {
2268 | g_dbus_method_invocation_return_value(invocation,
2269 | g_variant_new("(uu)", 0, 0));
2270 |
2271 | return;
2272 | }
2273 |
2274 | if (wlr_surface_is_xwayland_surface(wlr_surf)) {
2275 | struct wlr_xwayland_surface* xsurf;
2276 | xsurf = wlr_xwayland_surface_from_wlr_surface(wlr_surf);
2277 | g_dbus_method_invocation_return_value(
2278 | invocation, g_variant_new("(uu)", xsurf->width, xsurf->height));
2279 | }
2280 |
2281 | return;
2282 | }
2283 |
2284 | /*************** Other Actions ****************/
2285 | else
2286 | if (g_strcmp0(method_name, "inhibit_output_start") == 0)
2287 | {
2288 | g_variant_unref(parameters);
2289 | }
2290 | else
2291 | if (g_strcmp0(method_name, "inhibit_output_stop") == 0)
2292 | {
2293 | g_variant_unref(parameters);
2294 | }
2295 | else
2296 | if (g_strcmp0(method_name, "trigger_show_desktop") == 0)
2297 | {
2298 | g_variant_unref(parameters);
2299 | }
2300 | else
2301 | if (g_strcmp0(method_name, "trigger_show_overview") == 0)
2302 | {
2303 | g_variant_unref(parameters);
2304 | }
2305 | }
2306 |
2307 | static GVariant*
2308 | handle_get_property (GDBusConnection* connection,
2309 | const gchar* sender,
2310 | const gchar* object_path,
2311 | const gchar* interface_name,
2312 | const gchar* property_name, GError** error,
2313 | gpointer user_data)
2314 | {
2315 | // returning nullptr would crash compositor
2316 | GVariant* ret = g_variant_new_string("nullptr");
2317 |
2318 | // kept as an example
2319 | // if (g_strcmp0(property_name, "view_vector_ids") == 0)
2320 | // {
2321 | // std::vector> view_vector =
2322 | // core.get_all_views();
2323 |
2324 | // GVariantBuilder builder;
2325 | // g_variant_builder_init(&builder, G_VARIANT_TYPE("au"));
2326 | // for (auto it = begin(view_vector); it != end(view_vector); ++it)
2327 | // g_variant_builder_add(&builder, "u", it->get()->get_id());
2328 | // ret = g_variant_builder_end(&builder);
2329 | // }
2330 |
2331 | /* unused */
2332 | return ret;
2333 | }
2334 |
2335 | static gboolean
2336 | handle_set_property (GDBusConnection* connection,
2337 | const gchar* sender,
2338 | const gchar* object_path,
2339 | const gchar* interface_name,
2340 | const gchar* property_name, GVariant* value,
2341 | GError** error, gpointer user_data)
2342 | {
2343 | /* unused */
2344 | return false;
2345 | }
2346 |
2347 | static const GDBusInterfaceVTable interface_vtable = {
2348 | handle_method_call, handle_get_property, handle_set_property, {0}
2349 | };
2350 |
2351 | static gboolean
2352 | bus_emit_signal (gchar* signal_name, GVariant* signal_data)
2353 | {
2354 | GError* local_error = NULL;
2355 | if (!dbus_connection) {
2356 | if (signal_data != nullptr) {
2357 | g_variant_unref(signal_data);
2358 | }
2359 |
2360 | return true;
2361 | }
2362 |
2363 | g_dbus_connection_emit_signal(
2364 | dbus_connection, nullptr, "/org/wayland/compositor",
2365 | "org.wayland.compositor", signal_name, signal_data, &local_error);
2366 | g_assert_no_error(local_error);
2367 |
2368 | if (signal_data != nullptr) {
2369 | g_variant_unref(signal_data);
2370 | }
2371 |
2372 | return true;
2373 | }
2374 |
2375 | static void
2376 | on_bus_acquired (GDBusConnection* connection, const gchar* name,
2377 | gpointer user_data)
2378 | {
2379 | uint registration_id;
2380 |
2381 | dbus_connection = connection;
2382 | registration_id = g_dbus_connection_register_object(
2383 | connection, "/org/wayland/compositor", introspection_data->interfaces[0],
2384 | &interface_vtable, nullptr, nullptr, nullptr);
2385 | #ifdef DBUS_PLUGIN_DEBUG
2386 | LOG(wf::log::LOG_LEVEL_DEBUG, "Acquired the Bus");
2387 | #endif
2388 | }
2389 |
2390 | static void
2391 | on_name_acquired (GDBusConnection* connection, const gchar* name,
2392 | gpointer user_data)
2393 | {
2394 | #ifdef DBUS_PLUGIN_DEBUG
2395 | LOG(wf::log::LOG_LEVEL_DEBUG,
2396 | "Acquired the name " + std::string(name) + "on the session bus\n");
2397 | #endif
2398 | }
2399 |
2400 | static void
2401 | on_name_lost (GDBusConnection* connection, const gchar* name,
2402 | gpointer user_data)
2403 | {
2404 | #ifdef DBUS_PLUGIN_DEBUG
2405 | LOG(wf::log::LOG_LEVEL_DEBUG,
2406 | "Lost the name " + std::string(name) + "on the session bus");
2407 | #endif
2408 | }
2409 |
2410 | static void
2411 | acquire_bus ()
2412 | {
2413 | GBusNameOwnerFlags flags;
2414 | // flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE;
2415 | introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, nullptr);
2416 |
2417 | owner_id = g_bus_own_name(G_BUS_TYPE_SESSION, "org.wayland.compositor", flags,
2418 | on_bus_acquired, on_name_acquired, on_name_lost,
2419 | nullptr, nullptr);
2420 | }
2421 |
--------------------------------------------------------------------------------