1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
wf-kill: cancel a pending selection when the output is inhibited (session lock)
and restore the cursor when the last grabbed output is removed.
- grab_interface becomes a member of wf_kill_view with a .cancel handler.
output_t::set_inhibited(true) (session lock) calls cancel_active_plugins();
previously wf-kill had no cancel callback, so its grab and activation
survived the lock and the first left click after unlock closed (and with
-k SIGKILLed) the window under the pointer.
- New wf_kill_view::cancel_grab(): release all grabs, drop the pending
pirate-cursor idle call, restore the default cursor, send cancel to the
requester. Used by the cancel handler and by the output pre-remove path,
which previously did not restore the cursor.
diff --git a/src/plugin/wayfire-kill-view.cpp b/src/plugin/wayfire-kill-view.cpp
index 3c657b7..64fb13b 100644
--- a/src/plugin/wayfire-kill-view.cpp
+++ b/src/plugin/wayfire-kill-view.cpp
@@ -38,11 +38,6 @@
#include "wayfire-kill-view.hpp"
#include "wayfire-kill-view-server-protocol.h"
-wf::plugin_activation_data_t grab_interface{
- .name = "wf-kill",
- .capabilities = wf::CAPABILITY_GRAB_INPUT,
-};
-
static void bind_manager(wl_client *client, void *data,
uint32_t version, uint32_t id);
@@ -101,6 +96,24 @@ void wf_kill_view::release_grabs()
grab_active = false;
}
+/* Abort a live selection without closing anything (lock, output loss). */
+void wf_kill_view::cancel_grab()
+{
+ if (!grab_active)
+ {
+ return;
+ }
+
+ release_grabs();
+ idle_set_cursor.disconnect();
+ wf::get_core().set_cursor("default");
+ if (requester)
+ {
+ send_cancel(requester);
+ requester = nullptr;
+ }
+}
+
void wf_kill_view::start_grab(wl_resource *resource)
{
/* One selection at a time; replacing a live grab orphans its scene node. */
@@ -196,6 +209,13 @@ void wf_kill_view::set_base_ptr(wf::pointer_interaction_t *base)
wf_kill_view::wf_kill_view()
{
+ /* Output inhibition (session lock) cancels active plugins; without this
+ * the selection would survive the lock and fire on the next click. */
+ grab_interface.cancel = [=] ()
+ {
+ cancel_grab();
+ };
+
manager = wl_global_create(wf::get_core().display,
&wf_kill_view_base_interface, 1, this, bind_manager);
@@ -216,15 +236,9 @@ wf_kill_view::wf_kill_view()
it->second->ungrab_input();
ev->output->deactivate_plugin(&grab_interface);
input_grabs.erase(it);
- if (input_grabs.empty() && grab_active)
+ if (input_grabs.empty())
{
- grab_active = false;
- idle_set_cursor.disconnect();
- if (requester)
- {
- send_cancel(requester);
- requester = nullptr;
- }
+ cancel_grab();
}
};
wf::get_core().output_layout->connect(&on_output_pre_remove);
diff --git a/src/plugin/wayfire-kill-view.hpp b/src/plugin/wayfire-kill-view.hpp
index b7e5696..8e8210c 100644
--- a/src/plugin/wayfire-kill-view.hpp
+++ b/src/plugin/wayfire-kill-view.hpp
@@ -27,12 +27,17 @@
#include <wayfire/plugins/common/input-grab.hpp>
#include <wayfire/output-layout.hpp>
#include <wayfire/view.hpp>
+#include <wayfire/plugin.hpp>
class wf_kill_view
{
wl_global *manager;
public:
+ wf::plugin_activation_data_t grab_interface{
+ .name = "wf-kill",
+ .capabilities = wf::CAPABILITY_GRAB_INPUT,
+ };
wf::pointer_interaction_t *base;
void set_base_ptr(wf::pointer_interaction_t *base);
std::vector<wl_resource*> client_resources;
@@ -41,6 +46,7 @@ class wf_kill_view
bool grab_active = false;
void start_grab(wl_resource *resource);
void release_grabs();
+ void cancel_grab();
void client_destroyed(wl_resource *resource);
void close_view(wayfire_view view, wl_resource *resource);
void send_view_info(wl_resource *resource);
|