Skip to content

Commit 5147e98

Browse files
committed
api: deprecate is_positioned in view-mapped
Instead, we can use startup-x and startup-y properties
1 parent ce8c400 commit 5147e98

File tree

7 files changed

+113
-56
lines changed

7 files changed

+113
-56
lines changed

plugins/single_plugins/place.cpp

Lines changed: 85 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,139 @@
11
#include "wayfire/signal-provider.hpp"
22
#include "wayfire/toplevel-view.hpp"
3+
#include "wayfire/txn/transaction-manager.hpp"
34
#include <wayfire/per-output-plugin.hpp>
45
#include <wayfire/view.hpp>
56
#include <wayfire/core.hpp>
67
#include <wayfire/workarea.hpp>
78
#include <wayfire/window-manager.hpp>
89
#include <wayfire/signal-definitions.hpp>
910

10-
class wayfire_place_window : public wf::per_output_plugin_instance_t
11+
class wayfire_place_cascade_data : public wf::custom_data_t
1112
{
12-
wf::signal::connection_t<wf::view_mapped_signal> on_view_mapped = [=] (wf::view_mapped_signal *ev)
13+
public:
14+
int x = 0;
15+
int y = 0;
16+
};
17+
18+
class wayfire_place_window : public wf::plugin_interface_t
19+
{
20+
wf::signal::connection_t<wf::txn::new_transaction_signal> on_new_tx =
21+
[=] (wf::txn::new_transaction_signal *ev)
1322
{
14-
auto toplevel = wf::toplevel_cast(ev->view);
23+
// For each transaction, we need to consider what happens with participating views
24+
for (const auto& obj : ev->tx->get_objects())
25+
{
26+
auto toplevel = std::dynamic_pointer_cast<wf::toplevel_t>(obj);
27+
if (!toplevel || !map_pending(toplevel))
28+
{
29+
continue;
30+
}
31+
32+
auto view = wf::find_view_for_toplevel(toplevel);
33+
if (!view || !should_place(view))
34+
{
35+
continue;
36+
}
37+
}
38+
};
1539

16-
if (!toplevel || toplevel->parent || toplevel->pending_fullscreen() ||
17-
toplevel->pending_tiled_edges() || ev->is_positioned)
40+
bool map_pending(std::shared_ptr<wf::toplevel_t> toplevel)
41+
{
42+
return !toplevel->current().mapped && toplevel->pending().mapped;
43+
}
44+
45+
bool should_place(wayfire_toplevel_view toplevel)
46+
{
47+
if (toplevel->parent)
1848
{
19-
return;
49+
return false;
50+
}
51+
52+
if (toplevel->pending_fullscreen() || toplevel->pending_tiled_edges())
53+
{
54+
return false;
55+
}
56+
57+
if (toplevel->has_property("startup-x") || toplevel->has_property("startup-y"))
58+
{
59+
return false;
2060
}
2161

22-
ev->is_positioned = true;
62+
if (!toplevel->get_output())
63+
{
64+
return false;
65+
}
66+
67+
return true;
68+
}
69+
70+
void do_place(wayfire_toplevel_view view)
71+
{
72+
auto output = view->get_output();
2373
auto workarea = output->workarea->get_workarea();
2474

2575
std::string mode = placement_mode;
2676
if (mode == "cascade")
2777
{
28-
cascade(toplevel, workarea);
78+
cascade(view, workarea);
2979
} else if (mode == "maximize")
3080
{
31-
maximize(toplevel, workarea);
81+
maximize(view, workarea);
3282
} else if (mode == "random")
3383
{
34-
random(toplevel, workarea);
84+
random(view, workarea);
3585
} else
3686
{
37-
center(toplevel, workarea);
87+
center(view, workarea);
3888
}
39-
};
89+
}
4090

41-
wf::signal::connection_t<wf::workarea_changed_signal> workarea_changed_cb = [=] (auto)
91+
void adjust_cascade_for_workarea(nonstd::observer_ptr<wayfire_place_cascade_data> cascade,
92+
wf::geometry_t workarea)
4293
{
43-
auto workarea = output->workarea->get_workarea();
44-
if ((cascade_x < workarea.x) ||
45-
(cascade_x > workarea.x + workarea.width))
94+
if ((cascade->x < workarea.x) || (cascade->x > workarea.x + workarea.width))
4695
{
47-
cascade_x = workarea.x;
96+
cascade->x = workarea.x;
4897
}
4998

50-
if ((cascade_y < workarea.y) ||
51-
(cascade_y > workarea.y + workarea.height))
99+
if ((cascade->y < workarea.y) || (cascade->y > workarea.y + workarea.height))
52100
{
53-
cascade_y = workarea.y;
101+
cascade->y = workarea.y;
54102
}
55-
};
103+
}
56104

57105
wf::option_wrapper_t<std::string> placement_mode{"place/mode"};
58106

59-
int cascade_x, cascade_y;
60-
61107
public:
62108
void init() override
63109
{
64-
auto workarea = output->workarea->get_workarea();
65-
cascade_x = workarea.x;
66-
cascade_y = workarea.y;
67-
68-
output->connect(&workarea_changed_cb);
69-
output->connect(&on_view_mapped);
110+
wf::get_core().tx_manager->connect(&on_new_tx);
70111
}
71112

72-
void cascade(wayfire_toplevel_view & view, wf::geometry_t workarea)
113+
void cascade(wayfire_toplevel_view view, wf::geometry_t workarea)
73114
{
74115
wf::geometry_t window = view->get_pending_geometry();
116+
auto cascade = view->get_output()->get_data_safe<wayfire_place_cascade_data>();
117+
adjust_cascade_for_workarea(cascade, workarea);
75118

76-
if ((cascade_x + window.width > workarea.x + workarea.width) ||
77-
(cascade_y + window.height > workarea.y + workarea.height))
119+
if ((cascade->x + window.width > workarea.x + workarea.width) ||
120+
(cascade->y + window.height > workarea.y + workarea.height))
78121
{
79-
cascade_x = workarea.x;
80-
cascade_y = workarea.y;
122+
cascade->x = workarea.x;
123+
cascade->y = workarea.y;
81124
}
82125

83-
view->move(cascade_x, cascade_y);
126+
view->toplevel()->pending().geometry.x = cascade->x;
127+
view->toplevel()->pending().geometry.y = cascade->y;
84128

85-
cascade_x += workarea.width * .03;
86-
cascade_y += workarea.height * .03;
129+
cascade->x += workarea.width * .03;
130+
cascade->y += workarea.height * .03;
87131
}
88132

89133
void random(wayfire_toplevel_view & view, wf::geometry_t workarea)
90134
{
91135
wf::geometry_t window = view->get_pending_geometry();
92136
wf::geometry_t area;
93-
int pos_x, pos_y;
94137

95138
area.x = workarea.x;
96139
area.y = workarea.y;
@@ -104,18 +147,15 @@ class wayfire_place_window : public wf::per_output_plugin_instance_t
104147
return;
105148
}
106149

107-
pos_x = rand() % area.width + area.x;
108-
pos_y = rand() % area.height + area.y;
109-
110-
view->move(pos_x, pos_y);
150+
view->toplevel()->pending().geometry.x = rand() % area.width + area.x;
151+
view->toplevel()->pending().geometry.y = rand() % area.height + area.y;
111152
}
112153

113154
void center(wayfire_toplevel_view & view, wf::geometry_t workarea)
114155
{
115156
wf::geometry_t window = view->get_pending_geometry();
116-
window.x = workarea.x + (workarea.width / 2) - (window.width / 2);
117-
window.y = workarea.y + (workarea.height / 2) - (window.height / 2);
118-
view->move(window.x, window.y);
157+
view->toplevel()->pending().geometry.x = workarea.x + (workarea.width / 2) - (window.width / 2);
158+
view->toplevel()->pending().geometry.y = workarea.y + (workarea.height / 2) - (window.height / 2);
119159
}
120160

121161
void maximize(wayfire_toplevel_view & view, wf::geometry_t workarea)

src/api/wayfire/signal-definitions.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ struct view_mapped_signal
348348
wayfire_view view;
349349

350350
/* Indicates whether the position already has its initial position */
351+
[[deprecated("Use startup-x and startup-y properties instead")]]
351352
bool is_positioned = false;
352353
};
353354

src/api/wayfire/view-helpers.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "wayfire/scene.hpp"
66
#include <initializer_list>
77
#include <wayfire/view.hpp>
8+
#include <wayfire/toplevel-view.hpp>
89

910
// This file contains helper functions which are helpful when working with views. Most of the operations are
1011
// simply wrappers around more low-level functionality provided by views, scenegraph, etc.
@@ -47,7 +48,9 @@ wayfire_toplevel_view find_topmost_parent(wayfire_toplevel_view v);
4748
namespace view_implementation
4849
{
4950
void emit_toplevel_state_change_signals(wayfire_toplevel_view view, const wf::toplevel_state_t& old_state);
51+
[[deprecated("has position has been deprecated, use emit_view_map_signal(wayfire_view) instead")]]
5052
void emit_view_map_signal(wayfire_view view, bool has_position);
53+
void emit_view_map_signal(wayfire_view view);
5154
void emit_ping_timeout_signal(wayfire_view view);
5255
void emit_geometry_changed_signal(wayfire_toplevel_view view, wf::geometry_t old_geometry);
5356
void emit_title_changed_signal(wayfire_view view);

src/view/compositor-view.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ std::shared_ptr<wf::color_rect_view_t> wf::color_rect_view_t::create(view_role_t
119119
}
120120
}
121121

122-
wf::view_implementation::emit_view_map_signal(self, true);
122+
wf::view_implementation::emit_view_map_signal(self);
123123
return self;
124124
}
125125

src/view/view-impl.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "wayfire/output-layout.hpp"
1212
#include "wayfire/window-manager.hpp"
1313
#include "wayfire/workarea.hpp"
14-
#include "wayfire/workspace-set.hpp"
14+
#include "wayfire/workspace-set.hpp" // IWYU pragma: keep
1515
#include <memory>
1616
#include <wayfire/util/log.hpp>
1717
#include <wayfire/view-helpers.hpp>
@@ -32,6 +32,20 @@ void wf::view_implementation::emit_view_map_signal(wayfire_view view, bool has_p
3232
wf::get_core().emit(&data);
3333
}
3434

35+
void wf::view_implementation::emit_view_map_signal(wayfire_view view)
36+
{
37+
wf::view_mapped_signal data;
38+
data.view = view;
39+
40+
view->emit(&data);
41+
if (view->get_output())
42+
{
43+
view->get_output()->emit(&data);
44+
}
45+
46+
wf::get_core().emit(&data);
47+
}
48+
3549
void wf::view_implementation::emit_ping_timeout_signal(wayfire_view view)
3650
{
3751
wf::view_ping_timeout_signal data;
@@ -56,7 +70,7 @@ void wf::view_implementation::emit_geometry_changed_signal(wayfire_toplevel_view
5670

5771
void wf::view_interface_t::emit_view_map()
5872
{
59-
view_implementation::emit_view_map_signal(self(), false);
73+
view_implementation::emit_view_map_signal(self());
6074
}
6175

6276
void wf::view_interface_t::emit_view_unmap()

src/view/xwayland/xwayland-toplevel-view.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,12 @@ class wayfire_xwayland_view : public wf::toplevel_view_interface_t, public wayfi
5353
wlr_xwayland_surface_configure(xw, ev->x, ev->y, ev->width, ev->height);
5454
if ((ev->mask & XCB_CONFIG_WINDOW_X) && (ev->mask & XCB_CONFIG_WINDOW_Y))
5555
{
56-
this->self_positioned = true;
57-
toplevel->pending().geometry.x = ev->x - output_origin.x;
58-
toplevel->pending().geometry.y = ev->y - output_origin.y;
56+
int sx = ev->x - output_origin.x;
57+
int sy = ev->y - output_origin.y;
58+
this->set_property<int>("startup-x", sx);
59+
this->set_property<int>("startup-y", sy);
60+
toplevel->pending().geometry.x = sx;
61+
toplevel->pending().geometry.y = sy;
5962
}
6063

6164
return;
@@ -305,8 +308,7 @@ class wayfire_xwayland_view : public wf::toplevel_view_interface_t, public wayfi
305308
* manager determine this. We try to heuristically guess which of the
306309
* two cases we're dealing with by checking whether we have received
307310
* a valid ConfigureRequest before mapping */
308-
bool client_self_positioned = self_positioned;
309-
wf::view_implementation::emit_view_map_signal(self(), client_self_positioned);
311+
wf::view_implementation::emit_view_map_signal(self());
310312
}
311313

312314
void store_xw_geometry_unmapped()

src/view/xwayland/xwayland-view-base.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ class wayfire_xwayland_view_internal_base : public wf::xwayland_view_base_t
1919
protected:
2020
wf::wl_listener_wrapper on_configure;
2121

22-
/** The geometry requested by the client */
23-
bool self_positioned = false;
24-
2522
public:
2623
wayfire_xwayland_view_internal_base(wlr_xwayland_surface *xww) : xwayland_view_base_t(xww)
2724
{}

0 commit comments

Comments
 (0)