1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
--- a/plugins/grid/grid.cpp
+++ b/plugins/grid/grid.cpp
@@ -25,10 +25,49 @@
#include "wayfire/plugins/ipc/ipc-activator.hpp"
#include "wayfire/signal-provider.hpp"
#include <wayfire/view-helpers.hpp>
+#include <wayfire/scene-operations.hpp>
+#include <wayfire/unstable/translation-node.hpp>
namespace
{
const std::string grid_view_id = "grid-view";
+
+class grid_preview_node_t : public wf::scene::translation_node_t
+{
+ public:
+ std::optional<wf::scene::input_node_t> find_node_at(const wf::pointf_t&) override
+ {
+ return {};
+ }
+};
+
+class grid_preview_t : public wf::preview_indication_t
+{
+ std::shared_ptr<grid_preview_node_t> overlay;
+
+ public:
+ grid_preview_t(wf::geometry_t target, wf::output_t *output) :
+ wf::preview_indication_t(target, output, "move")
+ {
+ // The move helper renders the held window above all ordinary layers.
+ // Keep its drop target visible above that window, without taking input.
+ overlay = std::make_shared<grid_preview_node_t>();
+ overlay->set_offset(wf::origin(output->get_layout_geometry()));
+ wf::scene::readd_front(overlay, view->get_root_node());
+ wf::scene::add_front(wf::get_core().scene(), overlay);
+ view->set_geometry(target);
+ // Fade in at the actual destination; growing from the pointer makes
+ // short visits to an edge look like incomplete or moving targets.
+ set_target_geometry(target, 1);
+ }
+
+ ~grid_preview_t() override
+ {
+ view->damage();
+ view->close();
+ wf::scene::remove_child(overlay);
+ }
+};
class grid_scope_toggle_data_t : public wf::custom_data_t
{
@@ -87,7 +126,7 @@
wf::option_wrapper_t<int> quarter_snap_threshold{"move/quarter_snap_threshold"};
struct
{
- std::shared_ptr<wf::preview_indication_t> preview;
+ std::shared_ptr<grid_preview_t> preview;
wf::grid::slot_t slot_id = wf::grid::SLOT_NONE;
std::string zone;
wf::geometry_t geometry = {0, 0, 0, 0};
@@ -188,14 +227,7 @@
void clear_zone_preview()
{
- if (slot.preview)
- {
- // Dropping the helper alone leaves its compositor view mapped.
- slot.preview->view->damage();
- slot.preview->view->get_root_node()->set_enabled(false);
- slot.preview->view->close();
- slot.preview.reset();
- }
+ slot.preview.reset();
}
bool handle_zone_move(wf::grid::grid_handle_move_signal *ev)
@@ -250,9 +282,7 @@
clear_zone_preview();
slot.slot_id = wf::grid::SLOT_NONE;
slot.zone = zone->name;
- slot.preview = std::make_shared<wf::preview_indication_t>(
- wf::pointf_t{(double)ev->input.x, (double)ev->input.y}, ev->output, "move");
- slot.preview->set_target_geometry(zone->geometry, 1);
+ slot.preview = std::make_shared<grid_preview_t>(zone->geometry, ev->output);
}
return true;
@@ -468,14 +498,9 @@
return;
}
- /* Destroy previous preview */
- if (slot.preview)
- {
- auto input = ev->input;
- slot.preview->set_target_geometry(wf::pointf_t{(double)input.x, (double)input.y}, 0,
- true);
- slot.preview = nullptr;
- }
+ // Remove the old target immediately, including its scene node. A
+ // shrinking ghost should not trail the pointer or outlive the drag.
+ clear_zone_preview();
slot.slot_id = new_slot_id;
slot.geometry = slot_geometry;
@@ -489,10 +514,7 @@
return;
}
- auto input = ev->input;
- slot.preview = std::make_shared<wf::preview_indication_t>(
- wf::pointf_t{(double)input.x, (double)input.y}, ev->output, "move");
- slot.preview->set_target_geometry(slot_geometry, 1);
+ slot.preview = std::make_shared<grid_preview_t>(slot_geometry, ev->output);
}
};
|