window: Keep widgets in a tree instead of a list
This commit is contained in:
parent
30948989ee
commit
441338cb75
|
@ -334,7 +334,7 @@ panel_add_launcher(struct panel *panel, const char *icon, const char *path)
|
|||
launcher->panel = panel;
|
||||
wl_list_insert(panel->launcher_list.prev, &launcher->link);
|
||||
|
||||
launcher->widget = window_add_widget(panel->window, launcher);
|
||||
launcher->widget = widget_add_widget(panel->widget, launcher);
|
||||
widget_set_enter_handler(launcher->widget,
|
||||
panel_launcher_enter_handler);
|
||||
widget_set_leave_handler(launcher->widget,
|
||||
|
@ -508,7 +508,7 @@ unlock_dialog_create(struct desktop *desktop)
|
|||
window_set_user_data(dialog->window, dialog);
|
||||
window_set_keyboard_focus_handler(dialog->window,
|
||||
unlock_dialog_keyboard_focus_handler);
|
||||
dialog->button = window_add_widget(dialog->window, NULL);
|
||||
dialog->button = widget_add_widget(dialog->widget, dialog);
|
||||
widget_set_redraw_handler(dialog->widget,
|
||||
unlock_dialog_redraw_handler);
|
||||
widget_set_enter_handler(dialog->button,
|
||||
|
|
|
@ -134,7 +134,7 @@ struct window {
|
|||
window_drop_handler_t drop_handler;
|
||||
window_close_handler_t close_handler;
|
||||
|
||||
struct wl_list widget_list;
|
||||
struct widget *widget;
|
||||
struct widget *focus_widget;
|
||||
uint32_t widget_grab_button;
|
||||
|
||||
|
@ -146,6 +146,7 @@ struct window {
|
|||
|
||||
struct widget {
|
||||
struct window *window;
|
||||
struct wl_list child_list;
|
||||
struct wl_list link;
|
||||
struct rectangle allocation;
|
||||
widget_resize_handler_t resize_handler;
|
||||
|
@ -1036,24 +1037,28 @@ window_destroy(struct window *window)
|
|||
}
|
||||
|
||||
static struct widget *
|
||||
window_find_widget(struct window *window, int32_t x, int32_t y)
|
||||
widget_find_widget(struct widget *widget, int32_t x, int32_t y)
|
||||
{
|
||||
struct widget *widget;
|
||||
struct widget *child, *target;
|
||||
|
||||
wl_list_for_each(widget, &window->widget_list, link) {
|
||||
if (widget->allocation.x <= x &&
|
||||
x < widget->allocation.x + widget->allocation.width &&
|
||||
widget->allocation.y <= y &&
|
||||
y < widget->allocation.y + widget->allocation.height) {
|
||||
return widget;
|
||||
}
|
||||
wl_list_for_each(child, &widget->child_list, link) {
|
||||
target = widget_find_widget(child, x, y);
|
||||
if (target)
|
||||
return target;
|
||||
}
|
||||
|
||||
if (widget->allocation.x <= x &&
|
||||
x < widget->allocation.x + widget->allocation.width &&
|
||||
widget->allocation.y <= y &&
|
||||
y < widget->allocation.y + widget->allocation.height) {
|
||||
return widget;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct widget *
|
||||
window_add_widget(struct window *window, void *data)
|
||||
static struct widget *
|
||||
widget_create(struct window *window, void *data)
|
||||
{
|
||||
struct widget *widget;
|
||||
|
||||
|
@ -1062,18 +1067,36 @@ window_add_widget(struct window *window, void *data)
|
|||
widget->window = window;
|
||||
widget->user_data = data;
|
||||
widget->allocation = window->allocation;
|
||||
wl_list_insert(&window->widget_list, &widget->link);
|
||||
wl_list_init(&widget->child_list);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
struct widget *
|
||||
window_add_widget(struct window *window, void *data)
|
||||
{
|
||||
window->widget = widget_create(window, data);
|
||||
wl_list_init(&window->widget->link);
|
||||
|
||||
return window->widget;
|
||||
}
|
||||
|
||||
struct widget *
|
||||
widget_add_widget(struct widget *parent, void *data)
|
||||
{
|
||||
struct widget *widget;
|
||||
|
||||
widget = widget_create(parent->window, data);
|
||||
wl_list_insert(parent->child_list.prev, &widget->link);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
void
|
||||
window_for_each_widget(struct window *window, widget_func_t func, void *data)
|
||||
widget_destroy(struct widget *widget)
|
||||
{
|
||||
struct widget *widget;
|
||||
|
||||
wl_list_for_each(widget, &window->widget_list, link)
|
||||
func(widget, data);
|
||||
wl_list_remove(&widget->link);
|
||||
free(widget);
|
||||
}
|
||||
|
||||
struct widget *
|
||||
|
@ -1308,7 +1331,7 @@ input_handle_motion(void *data, struct wl_input_device *input_device,
|
|||
input->sy = sy;
|
||||
|
||||
if (!window->focus_widget || !window->widget_grab_button) {
|
||||
widget = window_find_widget(window, sx, sy);
|
||||
widget = widget_find_widget(window->widget, sx, sy);
|
||||
window_set_focus_widget(window, widget, input, time, sx, sy);
|
||||
}
|
||||
|
||||
|
@ -1425,7 +1448,8 @@ input_handle_button(void *data,
|
|||
if (window->focus_widget &&
|
||||
window->widget_grab_button == button && !state) {
|
||||
window->widget_grab_button = 0;
|
||||
widget = window_find_widget(window, input->sx, input->sy);
|
||||
widget = widget_find_widget(window->widget,
|
||||
input->sx, input->sy);
|
||||
window_set_focus_widget(window, widget, input, time,
|
||||
input->sx, input->sy);
|
||||
}
|
||||
|
@ -1500,7 +1524,7 @@ input_handle_pointer_focus(void *data,
|
|||
input->sy = sy;
|
||||
|
||||
pointer = POINTER_LEFT_PTR;
|
||||
widget = window_find_widget(window, sx, sy);
|
||||
widget = widget_find_widget(window->widget, sx, sy);
|
||||
window_set_focus_widget(window, widget, input, time, sx, sy);
|
||||
|
||||
pointer = input_get_pointer_image_for_location(input, pointer);
|
||||
|
@ -1878,7 +1902,6 @@ window_move(struct window *window, struct input *input, uint32_t time)
|
|||
static void
|
||||
window_resize(struct window *window, int32_t width, int32_t height)
|
||||
{
|
||||
struct widget *widget;
|
||||
struct rectangle allocation;
|
||||
|
||||
if (window->decoration) {
|
||||
|
@ -1896,15 +1919,14 @@ window_resize(struct window *window, int32_t width, int32_t height)
|
|||
window->allocation.width = width;
|
||||
window->allocation.height = height;
|
||||
|
||||
wl_list_for_each(widget, &window->widget_list, link) {
|
||||
if (widget->resize_handler)
|
||||
widget->resize_handler(widget,
|
||||
widget_set_allocation(window->widget, allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
|
||||
if (window->widget->resize_handler)
|
||||
window->widget->resize_handler(window->widget,
|
||||
allocation.width,
|
||||
allocation.height,
|
||||
widget->user_data);
|
||||
else
|
||||
widget->allocation = allocation;
|
||||
}
|
||||
window->widget->user_data);
|
||||
|
||||
window_schedule_redraw(window);
|
||||
}
|
||||
|
@ -2003,24 +2025,32 @@ window_set_child_size(struct window *window, int32_t width, int32_t height)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
widget_redraw(struct widget *widget)
|
||||
{
|
||||
struct widget *child;
|
||||
|
||||
if (widget->redraw_handler)
|
||||
widget->redraw_handler(widget, widget->user_data);
|
||||
wl_list_for_each(child, &widget->child_list, link)
|
||||
widget_redraw(child);
|
||||
}
|
||||
|
||||
static void
|
||||
idle_redraw(struct task *task, uint32_t events)
|
||||
{
|
||||
struct window *window =
|
||||
container_of(task, struct window, redraw_task);
|
||||
struct widget *widget;
|
||||
|
||||
window_create_surface(window);
|
||||
if (window->decoration)
|
||||
window_draw_decorations(window);
|
||||
|
||||
wl_list_for_each_reverse(widget, &window->widget_list, link)
|
||||
widget->redraw_handler(widget, widget->user_data);
|
||||
widget_redraw(window->widget);
|
||||
|
||||
window_flush(window);
|
||||
|
||||
window->redraw_scheduled = 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2181,8 +2211,6 @@ window_create_internal(struct display *display, struct window *parent,
|
|||
window->decoration = 1;
|
||||
window->transparent = 1;
|
||||
|
||||
wl_list_init(&window->widget_list);
|
||||
|
||||
if (display->dpy)
|
||||
#ifdef HAVE_CAIRO_EGL
|
||||
/* FIXME: make TYPE_EGL_IMAGE choosable for testing */
|
||||
|
|
|
@ -215,14 +215,9 @@ window_destroy(struct window *window);
|
|||
struct widget *
|
||||
window_add_widget(struct window *window, void *data);
|
||||
|
||||
typedef void (*widget_func_t)(struct widget *widget, void *data);
|
||||
|
||||
typedef void (*data_func_t)(void *data, size_t len,
|
||||
int32_t x, int32_t y, void *user_data);
|
||||
|
||||
void
|
||||
window_for_each_widget(struct window *window, widget_func_t func, void *data);
|
||||
|
||||
struct widget *
|
||||
window_get_focus_widget(struct window *window);
|
||||
struct display *
|
||||
|
@ -329,6 +324,10 @@ window_set_title(struct window *window, const char *title);
|
|||
const char *
|
||||
window_get_title(struct window *window);
|
||||
|
||||
struct widget *
|
||||
widget_add_widget(struct widget *parent, void *data);
|
||||
void
|
||||
widget_destroy(struct widget *widget);
|
||||
void
|
||||
widget_get_allocation(struct widget *widget, struct rectangle *allocation);
|
||||
|
||||
|
|
Loading…
Reference in New Issue