Skip to content

Commit 8d84b7f

Browse files
committed
refactor: Only (re)compute layout and pointer focus on frame or pointer move.
1 parent 7862a1a commit 8d84b7f

File tree

19 files changed

+294
-186
lines changed

19 files changed

+294
-186
lines changed

doc/ROADMAP.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,9 @@ See the [Detailed Feature List](FEATURES.md) for details.
3737

3838
* Infrastructure
3939
* [done] Support copy-paste and middle-click paste ([#399](https://github.com/phkaeser/wlmaker/issues/399)).
40+
* [done] Refactors pointer focus and layout computation to compute only once per frame.
4041
* [done] Adds `wlmtool` to parse XDG desktop files: Eliminates need for `wmmenugen`.
4142
* Fix: Handle `Terminal` flag and launch applications in a suitable terminal.
42-
* Recompute pointer focus max once per frame.
43-
* [done] Add wlmtk_output_tracker_t for keeping all outputs tracker.
44-
* [done] Use wlmtk_output_tracker_t in wlmtk_layer_t, wlmaker_background_t and wlmaker_lock_t.
4543
* Read keymap from `/etc/default/keyboard` or similar.
4644
* Support keypad (tap to click) and middle click alternatives.
4745
* Support configurable means (eg. Alt+) to emulate right-click on laptop.

include/toolkit/bordered.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ extern "C" {
4040
struct _wlmtk_bordered_t {
4141
/** Super class of the bordered. */
4242
wlmtk_container_t super_container;
43-
/** Virtual method table of the super container before extending it. */
44-
wlmtk_container_vmt_t orig_super_container_vmt;
43+
/** Virtual method table of the super element before extending it. */
44+
wlmtk_element_vmt_t orig_super_element_vmt;
4545

4646
/** Points to the element that will be enclosed by the border. */
4747
wlmtk_element_t *element_ptr;

include/toolkit/box.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
#include "libbase/libbase.h"
2626

27-
#include "container.h"
27+
#include "container.h" // IWYU pragma: keep
2828
#include "element.h"
2929
#include "style.h"
3030

@@ -47,8 +47,8 @@ typedef enum {
4747
struct _wlmtk_box_t {
4848
/** Super class of the box. */
4949
wlmtk_container_t super_container;
50-
/** Virtual method table of the superclass' container. */
51-
wlmtk_container_vmt_t orig_super_container_vmt;
50+
/** Virtual method table of the superclass' element. */
51+
wlmtk_element_vmt_t orig_super_element_vmt;
5252
/** Orientation of the box. */
5353
wlmtk_box_orientation_t orientation;
5454

include/toolkit/container.h

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,29 +38,13 @@ typedef struct _wlmtk_container_vmt_t wlmtk_container_vmt_t;
3838
extern "C" {
3939
#endif // __cplusplus
4040

41-
/** Virtual method table of the container. */
42-
struct _wlmtk_container_vmt_t {
43-
/**
44-
* Updates the layout of the container elements.
45-
*
46-
* @param container_ptr
47-
*
48-
* @return true if there was a change to the layout, eg. if elements got
49-
* re-positioned.
50-
*/
51-
bool (*update_layout)(wlmtk_container_t *container_ptr);
52-
};
53-
5441
/** State of the container. */
5542
struct _wlmtk_container_t {
5643
/** Super class of the container. */
5744
wlmtk_element_t super_element;
5845
/** Virtual method table of the super element before extending it. */
5946
wlmtk_element_vmt_t orig_super_element_vmt;
6047

61-
/** Virtual method table for the container. */
62-
wlmtk_container_vmt_t vmt;
63-
6448
/**
6549
* Elements contained here.
6650
*
@@ -85,8 +69,8 @@ struct _wlmtk_container_t {
8569
/** Stores the element with current keyboard focus. May be NULL. */
8670
wlmtk_element_t *keyboard_focus_element_ptr;
8771

88-
/** @private inhibitor, to prevent recursive layout updates. */
89-
bool inhibit_layout_update;
72+
/** @private Stores whether the layout had been invalidated. */
73+
bool invalidated_layout;
9074
};
9175

9276
/**
@@ -98,18 +82,6 @@ struct _wlmtk_container_t {
9882
*/
9983
bool wlmtk_container_init(wlmtk_container_t *container_ptr);
10084

101-
/**
102-
* Extends the container's virtual methods.
103-
*
104-
* @param container_ptr
105-
* @param container_vmt_ptr
106-
*
107-
* @return The previous virtual method table.
108-
*/
109-
wlmtk_container_vmt_t wlmtk_container_extend(
110-
wlmtk_container_t *container_ptr,
111-
const wlmtk_container_vmt_t *container_vmt_ptr);
112-
11385
/**
11486
* Initializes the container, and attach to WLR sene graph.
11587
*
@@ -254,18 +226,15 @@ void wlmtk_container_set_keyboard_focus_element(
254226
bool enabled);
255227

256228
/**
257-
* Updates the layout of the container, and recomputes pointer focus as needed.
229+
* Informs the container (and parents) that the layout needs to be recomputed.
258230
*
259231
* Must be called if an element is added or removed, or if any of the child
260232
* elements changes visibility or dimensions. Propagates to the parent
261233
* container(s).
262234
*
263-
* If needed: Trigger a poitner focus computation.
264-
*
265235
* @param container_ptr
266236
*/
267-
void wlmtk_container_update_layout_and_pointer_focus(
268-
wlmtk_container_t *container_ptr);
237+
void wlmtk_container_invalidate_layout(wlmtk_container_t *container_ptr);
269238

270239
/**
271240
* Returns the wlroots scene graph tree for this node.

include/toolkit/element.h

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
#include <libbase/libbase.h>
2424
#include <stdbool.h>
25-
#include <stddef.h>
2625
#include <stdint.h>
2726
#include <wayland-server-core.h>
2827
#include <xkbcommon/xkbcommon.h>
@@ -90,7 +89,7 @@ struct _wlmtk_element_vmt_t {
9089
* @param motion_event_ptr
9190
*
9291
* @return Whether the motion is accepted by this element (or any of it's
93-
* cohildren). In that case, the caller should accept this element as
92+
* children). In that case, the caller should accept this element as
9493
* having pointer focus.
9594
*/
9695
bool (*pointer_accepts_motion)(
@@ -175,6 +174,13 @@ struct _wlmtk_element_vmt_t {
175174
xkb_keysym_t keysym,
176175
enum xkb_key_direction direction,
177176
uint32_t modifiers);
177+
178+
/**
179+
* Redraws this element. For containers, will (re)arrange children.
180+
*
181+
* @param element_ptr
182+
*/
183+
void (*layout)(wlmtk_element_t *element_ptr);
178184
};
179185

180186
/** State of an element. */
@@ -438,6 +444,13 @@ void wlmtk_element_pointer_blur(wlmtk_element_t *element_ptr);
438444
*/
439445
void wlmtk_element_pointer_grab_cancel(wlmtk_element_t *element_ptr);
440446

447+
/** Calls @ref wlmtk_element_vmt_t::keyboard_blur. */
448+
static inline void wlmtk_element_keyboard_blur(
449+
wlmtk_element_t *element_ptr)
450+
{
451+
element_ptr->vmt.keyboard_blur(element_ptr);
452+
}
453+
441454
/** Calls @ref wlmtk_element_vmt_t::keyboard_event. */
442455
static inline bool wlmtk_element_keyboard_event(
443456
wlmtk_element_t *element_ptr,
@@ -458,13 +471,10 @@ static inline bool wlmtk_element_keyboard_sym(
458471
element_ptr, keysym, direction, modifiers);
459472
}
460473

461-
/** Calls @ref wlmtk_element_vmt_t::keyboard_blur. */
462-
static inline void wlmtk_element_keyboard_blur(
463-
wlmtk_element_t *element_ptr)
474+
/** Calls @ref wlmtk_element_vmt_t::layout, if given. */
475+
static inline void wlmtk_element_layout(wlmtk_element_t *element_ptr)
464476
{
465-
if (NULL != element_ptr->vmt.keyboard_blur) {
466-
element_ptr->vmt.keyboard_blur(element_ptr);
467-
}
477+
element_ptr->vmt.layout(element_ptr);
468478
}
469479

470480
/**
@@ -508,6 +518,8 @@ typedef struct {
508518
bool keyboard_event_called;
509519
/** Indicates that @ref wlmtk_element_vmt_t::keyboard_sym() was called. */
510520
bool keyboard_sym_called;
521+
/** Indicates that @ref wlmtk_element_vmt_t::layout() was called. */
522+
bool layout_called;
511523

512524
/** Last axis event received. */
513525
struct wlr_pointer_axis_event wlr_pointer_axis_event;

include/toolkit/panel.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include <stdbool.h>
2525
#include <stdint.h>
2626

27-
#include "container.h"
27+
#include "container.h" // IWYU pragma: keep
2828
#include "element.h"
2929

3030
/** Forward declaration: An element of a layer, we call it: Panel. */
@@ -90,9 +90,6 @@ struct _wlmtk_panel_t {
9090
/** The panel's virtual method table. */
9191
wlmtk_panel_vmt_t vmt;
9292

93-
/** Virtual method table of the superclass' container. */
94-
wlmtk_container_vmt_t orig_super_container_vmt;
95-
9693
/** Popup container. Panels may contain popups. */
9794
wlmtk_container_t popup_container;
9895

src/toolkit/bordered.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626

2727
/* == Declarations ========================================================= */
2828

29-
static bool _wlmtk_bordered_container_update_layout(
30-
wlmtk_container_t *container_ptr);
29+
static void _wlmtk_bordered_element_layout(wlmtk_element_t *element_ptr);
3130

3231
static wlmtk_rectangle_t * _wlmtk_bordered_create_border_rectangle(
3332
wlmtk_bordered_t *bordered_ptr);
@@ -38,9 +37,9 @@ static void _wlmtk_bordered_set_positions(wlmtk_bordered_t *bordered_ptr);
3837

3938
/* == Data ================================================================= */
4039

41-
/** Virtual method table: @ref wlmtk_container_t at @ref wlmtk_bordered_t. */
42-
static const wlmtk_container_vmt_t bordered_container_vmt = {
43-
.update_layout = _wlmtk_bordered_container_update_layout,
40+
/** Virtual method table: @ref wlmtk_element_t at @ref wlmtk_bordered_t. */
41+
static const wlmtk_element_vmt_t bordered_element_vmt = {
42+
.layout = _wlmtk_bordered_element_layout,
4443
};
4544

4645
/* == Exported methods ===================================================== */
@@ -55,8 +54,8 @@ bool wlmtk_bordered_init(wlmtk_bordered_t *bordered_ptr,
5554
if (!wlmtk_container_init(&bordered_ptr->super_container)) {
5655
return false;
5756
}
58-
bordered_ptr->orig_super_container_vmt = wlmtk_container_extend(
59-
&bordered_ptr->super_container, &bordered_container_vmt);
57+
bordered_ptr->orig_super_element_vmt = wlmtk_element_extend(
58+
wlmtk_bordered_element(bordered_ptr), &bordered_element_vmt);
6059

6160
bordered_ptr->element_ptr = element_ptr;
6261
wlmtk_container_add_element(&bordered_ptr->super_container,
@@ -106,7 +105,11 @@ void wlmtk_bordered_set_style(wlmtk_bordered_t *bordered_ptr,
106105
{
107106
bordered_ptr->style = *style_ptr;
108107

109-
_wlmtk_bordered_container_update_layout(&bordered_ptr->super_container);
108+
wlmtk_element_layout(wlmtk_bordered_element(bordered_ptr));
109+
if (NULL != wlmtk_bordered_element(bordered_ptr)->parent_container_ptr) {
110+
wlmtk_container_invalidate_layout(
111+
wlmtk_bordered_element(bordered_ptr)->parent_container_ptr);
112+
}
110113

111114
// Guard clause. Actually, if *any* of the rectangles was not created.
112115
if (NULL == bordered_ptr->western_border_rectangle_ptr) return;
@@ -133,16 +136,14 @@ wlmtk_element_t *wlmtk_bordered_element(wlmtk_bordered_t *bordered_ptr)
133136
/**
134137
* Updates the layout of the bordered element.
135138
*
136-
* @param container_ptr
139+
* @param element_ptr
137140
*/
138-
bool _wlmtk_bordered_container_update_layout(
139-
wlmtk_container_t *container_ptr)
141+
void _wlmtk_bordered_element_layout(wlmtk_element_t *element_ptr)
140142
{
141143
wlmtk_bordered_t *bordered_ptr = BS_CONTAINER_OF(
142-
container_ptr, wlmtk_bordered_t, super_container);
143-
144+
element_ptr, wlmtk_bordered_t, super_container.super_element);
145+
bordered_ptr->orig_super_element_vmt.layout(element_ptr);
144146
_wlmtk_bordered_set_positions(bordered_ptr);
145-
return true;
146147
}
147148

148149
/* ------------------------------------------------------------------------- */
@@ -292,9 +293,8 @@ void test_init_fini(bs_test_t *test_ptr)
292293
0, 2, 2, 20);
293294

294295
// Update layout, test updated positions.
295-
fe_ptr->dimensions.width = 200;
296-
fe_ptr->dimensions.height = 120;
297-
wlmtk_container_update_layout_and_pointer_focus(&bordered.super_container);
296+
wlmtk_fake_element_set_dimensions(fe_ptr, 200, 120);
297+
wlmtk_element_layout(wlmtk_bordered_element(&bordered));
298298
test_rectangle_pos(
299299
test_ptr, bordered.northern_border_rectangle_ptr,
300300
0, 0, 204, 2);

0 commit comments

Comments
 (0)