diff options
-rw-r--r-- | clients/desktop-shell.c | 133 | ||||
-rw-r--r-- | clients/dnd.c | 15 | ||||
-rw-r--r-- | clients/eventdemo.c | 35 | ||||
-rw-r--r-- | clients/flower.c | 35 | ||||
-rw-r--r-- | clients/gears.c | 19 | ||||
-rw-r--r-- | clients/image.c | 15 | ||||
-rw-r--r-- | clients/resizor.c | 13 | ||||
-rw-r--r-- | clients/tablet-shell.c | 3 | ||||
-rw-r--r-- | clients/terminal.c | 23 | ||||
-rw-r--r-- | clients/view.c | 12 | ||||
-rw-r--r-- | clients/window.c | 129 | ||||
-rw-r--r-- | clients/window.h | 26 |
12 files changed, 239 insertions, 219 deletions
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index ad1318d..7d8f526 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -42,7 +42,6 @@ struct desktop { struct display *display; struct desktop_shell *shell; - const char *background_path; struct unlock_dialog *unlock_dialog; struct task unlock_task; struct wl_list outputs; @@ -67,6 +66,7 @@ struct panel { struct background { struct surface base; struct window *window; + struct widget *widget; }; struct output { @@ -168,36 +168,34 @@ panel_launcher_activate(struct panel_launcher *widget) } static void -panel_draw_launcher(struct panel_launcher *launcher, void *data) +panel_launcher_redraw_handler(struct widget *widget, void *data) { - cairo_t *cr = data; - int x, y, width, height; - double dx, dy; - - width = cairo_image_surface_get_width(launcher->icon); - height = cairo_image_surface_get_height(launcher->icon); - x = 0; - y = -height / 2; + struct panel_launcher *launcher = data; + cairo_surface_t *surface; + struct rectangle allocation; + cairo_t *cr; + + surface = window_get_surface(launcher->panel->window); + cr = cairo_create(surface); + + widget_get_allocation(widget, &allocation); if (launcher->pressed) { - x++; - y++; + allocation.x++; + allocation.y++; } - dx = x; - dy = y; - cairo_user_to_device(cr, &dx, &dy); - widget_set_allocation(launcher->widget, dx, dy, width, height); - - cairo_set_source_surface(cr, launcher->icon, x, y); + cairo_set_source_surface(cr, launcher->icon, + allocation.x, allocation.y); cairo_paint(cr); if (window_get_focus_widget(launcher->panel->window) == launcher->widget) { cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4); - cairo_mask_surface(cr, launcher->icon, x, y); + cairo_mask_surface(cr, launcher->icon, + allocation.x, allocation.y); } - cairo_translate(cr, width + 10, 0); + cairo_destroy(cr); } static void @@ -211,24 +209,18 @@ set_hex_color(cairo_t *cr, uint32_t color) } static void -panel_redraw_handler(struct window *window, void *data) +panel_redraw_handler(struct widget *widget, void *data) { cairo_surface_t *surface; cairo_t *cr; - struct panel_launcher *launcher; - struct panel *panel = window_get_user_data(window); + struct panel *panel = data; - surface = window_get_surface(window); + surface = window_get_surface(panel->window); cr = cairo_create(surface); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); set_hex_color(cr, key_panel_color); cairo_paint(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_translate(cr, 10, 32 / 2); - wl_list_for_each(launcher, &panel->launcher_list, link) - panel_draw_launcher(launcher, cr); - cairo_destroy(cr); cairo_surface_destroy(surface); } @@ -267,22 +259,42 @@ panel_button_handler(struct widget *widget, struct input *input, uint32_t time, int button, int state, void *data) { - struct window *window = data; - struct panel *panel = window_get_user_data(window); + struct panel *panel = data; if (button == BTN_RIGHT && state) show_menu(panel, input, time); } static void +panel_resize_handler(struct widget *widget, + int32_t width, int32_t height, void *data) +{ + struct panel_launcher *launcher; + struct panel *panel = data; + int x, y, w, h; + + x = 10; + y = 16; + wl_list_for_each(launcher, &panel->launcher_list, link) { + w = cairo_image_surface_get_width(launcher->icon); + h = cairo_image_surface_get_height(launcher->icon); + widget_set_allocation(launcher->widget, + x, y - h / 2, w + 1, h + 1); + x += w + 10; + } +} + +static void panel_configure(void *data, struct desktop_shell *desktop_shell, uint32_t time, uint32_t edges, struct window *window, int32_t width, int32_t height) { - window_set_child_size(window, width, 32); - window_schedule_redraw(window); + struct surface *surface = window_get_user_data(window); + struct panel *panel = container_of(surface, struct panel, base); + + window_schedule_resize(panel->window, width, 32); } static struct panel * @@ -296,15 +308,16 @@ panel_create(struct display *display) panel->base.configure = panel_configure; panel->window = window_create(display, 0, 0); panel->widget = window_add_widget(panel->window, panel); + wl_list_init(&panel->launcher_list); window_set_title(panel->window, "panel"); window_set_decoration(panel->window, 0); - window_set_redraw_handler(panel->window, panel_redraw_handler); window_set_custom(panel->window); window_set_user_data(panel->window, panel); + widget_set_redraw_handler(panel->widget, panel_redraw_handler); + widget_set_resize_handler(panel->widget, panel_resize_handler); widget_set_button_handler(panel->widget, panel_button_handler); - wl_list_init(&panel->launcher_list); return panel; } @@ -319,7 +332,6 @@ panel_add_launcher(struct panel *panel, const char *icon, const char *path) launcher->icon = cairo_image_surface_create_from_png(icon); launcher->path = strdup(path); launcher->panel = panel; - wl_list_insert(panel->launcher_list.prev, &launcher->link); launcher->widget = window_add_widget(panel->window, launcher); @@ -329,31 +341,36 @@ panel_add_launcher(struct panel *panel, const char *icon, const char *path) panel_launcher_leave_handler); widget_set_button_handler(launcher->widget, panel_launcher_button_handler); + widget_set_redraw_handler(launcher->widget, + panel_launcher_redraw_handler); } static void -background_draw(struct window *window, int width, int height, const char *path) +background_draw(struct widget *widget, void *data) { + struct background *background = data; cairo_surface_t *surface, *image; cairo_pattern_t *pattern; cairo_matrix_t matrix; cairo_t *cr; double sx, sy; + struct rectangle allocation; - window_set_child_size(window, width, height); - window_create_surface(window); - surface = window_get_surface(window); + surface = window_get_surface(background->window); cr = cairo_create(surface); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 0.0, 0.0, 0.2, 1.0); cairo_paint(cr); - if (path) { - image = load_jpeg(path); + widget_get_allocation(widget, &allocation); + if (key_background_image) { + image = load_jpeg(key_background_image); pattern = cairo_pattern_create_for_surface(image); - sx = (double) cairo_image_surface_get_width(image) / width; - sy = (double) cairo_image_surface_get_height(image) / height; + sx = (double) cairo_image_surface_get_width(image) / + allocation.width; + sy = (double) cairo_image_surface_get_height(image) / + allocation.height; cairo_matrix_init_scale(&matrix, sx, sy); cairo_pattern_set_matrix(pattern, &matrix); cairo_set_source(cr, pattern); @@ -364,7 +381,6 @@ background_draw(struct window *window, int width, int height, const char *path) cairo_destroy(cr); cairo_surface_destroy(surface); - window_flush(window); } static void @@ -374,14 +390,18 @@ background_configure(void *data, struct window *window, int32_t width, int32_t height) { - struct desktop *desktop = data; + struct background *background = + (struct background *) window_get_user_data(window); - background_draw(window, width, height, desktop->background_path); + window_set_child_size(background->window, width, height); + widget_set_allocation(background->widget, 0, 0, width, height); + window_schedule_redraw(background->window); } static void -unlock_dialog_draw(struct unlock_dialog *dialog) +unlock_dialog_redraw_handler(struct widget *widget, void *data) { + struct unlock_dialog *dialog = data; struct rectangle allocation; cairo_t *cr; cairo_surface_t *surface; @@ -446,14 +466,6 @@ unlock_dialog_button_handler(struct widget *widget, } static void -unlock_dialog_redraw_handler(struct window *window, void *data) -{ - struct unlock_dialog *dialog = data; - - unlock_dialog_draw(dialog); -} - -static void unlock_dialog_keyboard_focus_handler(struct window *window, struct input *device, void *data) { @@ -494,10 +506,11 @@ unlock_dialog_create(struct desktop *desktop) window_set_custom(dialog->window); window_set_user_data(dialog->window, dialog); - window_set_redraw_handler(dialog->window, unlock_dialog_redraw_handler); window_set_keyboard_focus_handler(dialog->window, unlock_dialog_keyboard_focus_handler); dialog->button = window_add_widget(dialog->window, NULL); + widget_set_redraw_handler(dialog->widget, + unlock_dialog_redraw_handler); widget_set_enter_handler(dialog->button, unlock_dialog_widget_enter_handler); widget_set_leave_handler(dialog->button, @@ -508,7 +521,7 @@ unlock_dialog_create(struct desktop *desktop) desktop_shell_set_lock_surface(desktop->shell, window_get_wl_shell_surface(dialog->window)); - unlock_dialog_draw(dialog); + window_schedule_redraw(dialog->window); return dialog; } @@ -576,9 +589,11 @@ background_create(struct desktop *desktop) background->base.configure = background_configure; background->window = window_create(desktop->display, 0, 0); + background->widget = window_add_widget(background->window, background); window_set_decoration(background->window, 0); window_set_custom(background->window); window_set_user_data(background->window, background); + widget_set_redraw_handler(background->widget, background_draw); return background; } @@ -670,8 +685,6 @@ int main(int argc, char *argv[]) &desktop); free(config_file); - desktop.background_path = key_background_image; - signal(SIGCHLD, sigchild_handler); display_run(desktop.display); diff --git a/clients/dnd.c b/clients/dnd.c index cd03b1f..0498c5d 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -160,8 +160,9 @@ item_create(struct display *display, int x, int y, int seed) } static void -dnd_draw(struct dnd *dnd) +dnd_redraw_handler(struct widget *widget, void *data) { + struct dnd *dnd = data; struct rectangle allocation; cairo_t *cr; cairo_surface_t *surface; @@ -192,14 +193,6 @@ dnd_draw(struct dnd *dnd) } static void -redraw_handler(struct window *window, void *data) -{ - struct dnd *dnd = data; - - dnd_draw(dnd); -} - -static void keyboard_focus_handler(struct window *window, struct input *device, void *data) { @@ -530,12 +523,12 @@ dnd_create(struct display *display) } window_set_user_data(dnd->window, dnd); - window_set_redraw_handler(dnd->window, redraw_handler); window_set_keyboard_focus_handler(dnd->window, keyboard_focus_handler); window_set_data_handler(dnd->window, dnd_data_handler); window_set_drop_handler(dnd->window, dnd_drop_handler); + widget_set_redraw_handler(dnd->widget, dnd_redraw_handler); widget_set_enter_handler(dnd->widget, dnd_enter_handler); widget_set_motion_handler(dnd->widget, dnd_motion_handler); widget_set_button_handler(dnd->widget, dnd_button_handler); @@ -544,7 +537,7 @@ dnd_create(struct display *display) height = 4 * (item_height + item_padding) + item_padding; window_set_child_size(dnd->window, width, height); - dnd_draw(dnd); + window_schedule_redraw(dnd->window); return dnd; } diff --git a/clients/eventdemo.c b/clients/eventdemo.c index 5ea6831..5f70bc1 100644 --- a/clients/eventdemo.c +++ b/clients/eventdemo.c @@ -90,19 +90,23 @@ struct eventdemo { }; /** - * \brief Redraws the window + * \brief CALLBACK function, Wayland requests the window to redraw. + * \param window window to be redrawn + * \param data user data associated to the window * * Draws a red rectangle as demonstration of per-window data. */ static void -eventdemo_draw(struct eventdemo *e) { - if (log_redraw) - printf("redraw\n"); - +redraw_handler(struct widget *widget, void *data) +{ + struct eventdemo *e = data; cairo_surface_t *surface; cairo_t *cr; struct rectangle rect; + if (log_redraw) + printf("redraw\n"); + window_get_child_allocation(e->window, &rect); surface = window_get_surface(e->window); @@ -122,18 +126,6 @@ eventdemo_draw(struct eventdemo *e) { } /** - * \brief CALLBACK function, Wayland requests the window to redraw. - * \param window window to be redrawn - * \param data user data associated to the window - */ -static void -redraw_handler(struct window *window, void *data) -{ - struct eventdemo *e = data; - eventdemo_draw(e); -} - -/** * \brief CALLBACK function, Wayland requests the window to resize. * \param window window to be resized * \param width desired width @@ -142,7 +134,7 @@ redraw_handler(struct window *window, void *data) */ static void -resize_handler(struct window *window, +resize_handler(struct widget *widget, int32_t width, int32_t height, void *data) { struct eventdemo *e = data; @@ -159,9 +151,6 @@ resize_handler(struct window *window, /* set the new window dimensions */ window_set_child_size(e->window, width, height); - - /* inform Wayland that the window needs to be redrawn */ - window_schedule_redraw(e->window); } /** @@ -301,10 +290,10 @@ eventdemo_create(struct display *d) window_set_user_data(e->window, e); /* Set the callback redraw handler for the window */ - window_set_redraw_handler(e->window, redraw_handler); + widget_set_redraw_handler(e->widget, redraw_handler); /* Set the callback resize handler for the window */ - window_set_resize_handler(e->window, resize_handler); + widget_set_resize_handler(e->widget, resize_handler); /* Set the callback focus handler for the window */ window_set_keyboard_focus_handler(e->window, diff --git a/clients/flower.c b/clients/flower.c index 42028f0..9cbc424 100644 --- a/clients/flower.c +++ b/clients/flower.c @@ -104,6 +104,23 @@ draw_stuff(cairo_surface_t *surface, int width, int height) cairo_destroy(cr); } +static void +redraw_handler(struct widget *widget, void *data) +{ + struct flower *flower = data; + cairo_surface_t *surface; + + surface = window_get_surface(flower->window); + if (surface == NULL || + cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "failed to create cairo egl surface\n"); + return; + } + + draw_stuff(surface, flower->width, flower->height); + cairo_surface_destroy(surface); +} + static int motion_handler(struct widget *widget, struct input *input, uint32_t time, int32_t x, int32_t y, void *data) @@ -124,7 +141,6 @@ button_handler(struct widget *widget, int main(int argc, char *argv[]) { - cairo_surface_t *s; struct flower flower; struct display *d; struct timeval tv; @@ -144,23 +160,14 @@ int main(int argc, char *argv[]) flower.window = window_create(d, flower.width, flower.height); flower.widget = window_add_widget(flower.window, &flower); - window_set_title(flower.window, "flower"); window_set_decoration(flower.window, 0); - window_create_surface(flower.window); - s = window_get_surface(flower.window); - if (s == NULL || cairo_surface_status (s) != CAIRO_STATUS_SUCCESS) { - fprintf(stderr, "failed to create cairo egl surface\n"); - return -1; - } - - draw_stuff(s, flower.width, flower.height); - cairo_surface_flush(s); - cairo_surface_destroy(s); - window_flush(flower.window); + widget_set_redraw_handler(flower.widget, redraw_handler); widget_set_motion_handler(flower.widget, motion_handler); widget_set_button_handler(flower.widget, button_handler); - window_set_user_data(flower.window, &flower); + + window_schedule_redraw(flower.window); + display_run(d); return 0; diff --git a/clients/gears.c b/clients/gears.c index b5e7bd4..5dfb47a 100644 --- a/clients/gears.c +++ b/clients/gears.c @@ -42,6 +42,7 @@ struct gears { struct window *window; + struct widget *widget; struct display *d; @@ -212,7 +213,7 @@ static const struct wl_callback_listener listener = { }; static void -redraw_handler(struct window *window, void *data) +redraw_handler(struct widget *widget, void *data) { GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; struct rectangle window_allocation; @@ -277,7 +278,7 @@ redraw_handler(struct window *window, void *data) } static void -resize_handler(struct window *window, +resize_handler(struct widget *widget, int32_t width, int32_t height, void *data) { struct gears *gears = data; @@ -299,11 +300,7 @@ static void keyboard_focus_handler(struct window *window, struct input *device, void *data) { - struct gears *gears = data; - struct rectangle allocation; - - window_get_child_allocation(gears->window, &allocation); - resize_handler(window, allocation.width, allocation.height, gears); + window_schedule_redraw(window); } static struct gears * @@ -317,6 +314,7 @@ gears_create(struct display *display) memset(gears, 0, sizeof *gears); gears->d = display; gears->window = window_create(display, width, height); + gears->widget = window_add_widget(gears->window, gears); window_set_transparent(gears->window, 0); window_set_title(gears->window, "Wayland Gears"); @@ -358,9 +356,10 @@ gears_create(struct display *display) glClearColor(0, 0, 0, 0.92); window_set_user_data(gears->window, gears); - window_set_resize_handler(gears->window, resize_handler); - window_set_redraw_handler(gears->window, redraw_handler); - window_set_keyboard_focus_handler(gears->window, keyboard_focus_handler); + widget_set_resize_handler(gears->widget, resize_handler); + widget_set_redraw_handler(gears->widget, redraw_handler); + window_set_keyboard_focus_handler(gears->window, + keyboard_focus_handler); frame_callback(gears, NULL, 0); diff --git a/clients/image.c b/clients/image.c index 0e34103..517bb47 100644 --- a/clients/image.c +++ b/clients/image.c @@ -39,6 +39,7 @@ struct image { struct window *window; + struct widget *widget; struct display *display; gchar *filename; }; @@ -133,8 +134,9 @@ set_source_pixbuf(cairo_t *cr, } static void -image_draw(struct image *image) +redraw_handler(struct widget *widget, void *data) { + struct image *image = data; struct rectangle allocation; GdkPixbuf *pb; cairo_t *cr; @@ -177,14 +179,6 @@ image_draw(struct image *image) } static void -redraw_handler(struct window *window, void *data) -{ - struct image *image = data; - - image_draw(image); -} - -static void keyboard_focus_handler(struct window *window, struct input *device, void *data) { @@ -212,11 +206,12 @@ image_create(struct display *display, const char *filename) image->filename = g_strdup(filename); image->window = window_create(display, 500, 400); + image->widget = window_add_widget(image->window, image); window_set_title(image->window, title); image->display = display; window_set_user_data(image->window, image); - window_set_redraw_handler(image->window, redraw_handler); + widget_set_redraw_handler(image->widget, redraw_handler); window_set_keyboard_focus_handler(image->window, keyboard_focus_handler); diff --git a/clients/resizor.c b/clients/resizor.c index 395fdcd..945f2ae 100644 --- a/clients/resizor.c +++ b/clients/resizor.c @@ -98,8 +98,9 @@ frame_callback(void *data, struct wl_callback *callback, uint32_t time) } static void -resizor_draw(struct resizor *resizor) +redraw_handler(struct widget *widget, void *data) { + struct resizor *resizor = data; cairo_surface_t *surface; cairo_t *cr; struct rectangle allocation; @@ -123,14 +124,6 @@ resizor_draw(struct resizor *resizor) } static void -redraw_handler(struct window *window, void *data) -{ - struct resizor *resizor = data; - - resizor_draw(resizor); -} - -static void keyboard_focus_handler(struct window *window, struct input *device, void *data) { @@ -219,7 +212,7 @@ resizor_create(struct display *display) window_set_key_handler(resizor->window, key_handler); window_set_user_data(resizor->window, resizor); - window_set_redraw_handler(resizor->window, redraw_handler); + widget_set_redraw_handler(resizor->widget, redraw_handler); window_set_keyboard_focus_handler(resizor->window, keyboard_focus_handler); diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c index 90cb766..2331e68 100644 --- a/clients/tablet-shell.c +++ b/clients/tablet-shell.c @@ -202,8 +202,7 @@ lockscreen_button_handler(struct widget *widget, struct input *input, uint32_t time, int button, int state, void *data) { - struct window *window = data; - struct tablet_shell *shell = window_get_user_data(window); + struct tablet_shell *shell = data; window_destroy(shell->lockscreen); shell->lockscreen = NULL; diff --git a/clients/terminal.c b/clients/terminal.c index 9c3c56b..b6e3139 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -722,8 +722,6 @@ terminal_resize(struct terminal *terminal, int width, int height) pixel_width, pixel_height); } - window_schedule_redraw (terminal->window); - data_pitch = width * sizeof(union utf8_char); size = data_pitch * height; data = malloc(size); @@ -899,9 +897,11 @@ glyph_run_add(struct glyph_run *run, int x, int y, union utf8_char *c) run->count += num_glyphs; } + static void -terminal_draw_contents(struct terminal *terminal) +redraw_handler(struct widget *widget, void *data) { + struct terminal *terminal = data; struct rectangle allocation; cairo_t *cr; int top_margin, side_margin; @@ -1011,7 +1011,7 @@ terminal_write(struct terminal *terminal, const char *data, size_t length) } static void -resize_handler(struct window *window, +resize_handler(struct widget *widget, int32_t pixel_width, int32_t pixel_height, void *data) { struct terminal *terminal = data; @@ -1030,14 +1030,6 @@ resize_handler(struct window *window, } static void -redraw_handler(struct window *window, void *data) -{ - struct terminal *terminal = data; - - terminal_draw_contents(terminal); -} - -static void terminal_data(struct terminal *terminal, const char *data, size_t length); static void @@ -1498,7 +1490,7 @@ handle_escape(struct terminal *terminal) if (set[1] && set[2]) { window_set_child_size(terminal->window, args[2], args[1]); - resize_handler(terminal->window, + resize_handler(terminal->widget, args[2], args[1], terminal); } break; @@ -2285,12 +2277,11 @@ terminal_create(struct display *display, int fullscreen) terminal->margin = 5; window_set_user_data(terminal->window, terminal); - window_set_redraw_handler(terminal->window, redraw_handler); - window_set_resize_handler(terminal->window, resize_handler); - window_set_key_handler(terminal->window, key_handler); window_set_keyboard_focus_handler(terminal->window, keyboard_focus_handler); + widget_set_redraw_handler(terminal->widget, redraw_handler); + widget_set_resize_handler(terminal->widget, resize_handler); widget_set_button_handler(terminal->widget, button_handler); widget_set_motion_handler(terminal->widget, motion_handler); diff --git a/clients/view.c b/clients/view.c index 1a345e6..6c12f97 100644 --- a/clients/view.c +++ b/clients/view.c @@ -111,7 +111,7 @@ view_draw(struct view *view) } static void -redraw_handler(struct window *window, void *data) +redraw_handler(struct widget *widget, void *data) { struct view *view = data; @@ -119,7 +119,7 @@ redraw_handler(struct window *window, void *data) } static void -resize_handler(struct window *window, +resize_handler(struct widget *widget, int32_t width, int32_t height, void *data) { struct view *view = data; @@ -248,13 +248,13 @@ view_create(struct display *display, view->display = display; window_set_user_data(view->window, view); - window_set_redraw_handler(view->window, redraw_handler); - window_set_resize_handler(view->window, resize_handler); window_set_key_handler(view->window, key_handler); window_set_keyboard_focus_handler(view->window, keyboard_focus_handler); - widget_set_button_handler(window_get_widget(view->window), - button_handler); + widget_set_button_handler(view->widget, button_handler); + widget_set_resize_handler(view->widget, resize_handler); + widget_set_redraw_handler(view->widget, redraw_handler); + view->page = 0; view->fullscreen = fullscreen; diff --git a/clients/window.c b/clients/window.c index 5f80721..b736b81 100644 --- a/clients/window.c +++ b/clients/window.c @@ -115,6 +115,8 @@ struct window { int resize_edges; int redraw_scheduled; struct task redraw_task; + int resize_scheduled; + struct task resize_task; int minimum_width, minimum_height; int margin; int type; @@ -126,8 +128,6 @@ struct window { cairo_surface_t *cairo_surface, *pending_surface; - window_resize_handler_t resize_handler; - window_redraw_handler_t redraw_handler; window_key_handler_t key_handler; window_keyboard_focus_handler_t keyboard_focus_handler; window_data_handler_t data_handler; @@ -148,6 +148,8 @@ struct widget { struct window *window; struct wl_list link; struct rectangle allocation; + widget_resize_handler_t resize_handler; + widget_redraw_handler_t redraw_handler; widget_enter_handler_t enter_handler; widget_leave_handler_t leave_handler; widget_motion_handler_t motion_handler; @@ -1009,6 +1011,8 @@ window_destroy(struct window *window) if (window->redraw_scheduled) wl_list_remove(&window->redraw_task.link); + if (window->resize_scheduled) + wl_list_remove(&window->resize_task.link); wl_list_for_each(input, &display->input_list, link) { if (input->pointer_focus == window) @@ -1101,6 +1105,20 @@ widget_get_user_data(struct widget *widget) } void +widget_set_resize_handler(struct widget *widget, + widget_resize_handler_t handler) +{ + widget->resize_handler = handler; +} + +void +widget_set_redraw_handler(struct widget *widget, + widget_redraw_handler_t handler) +{ + widget->redraw_handler = handler; +} + +void widget_set_enter_handler(struct widget *widget, widget_enter_handler_t handler) { widget->enter_handler = handler; @@ -1858,39 +1876,75 @@ 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) { + allocation.x = 20; + allocation.y = 60; + allocation.width = width - 20 - window->margin * 2; + allocation.height = height - 60 - window->margin * 2; + } else { + allocation.x = 0; + allocation.y = 0; + allocation.width = width; + allocation.height = 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, + allocation.width, + allocation.height, + widget->user_data); + else + widget->allocation = allocation; + } + + window_schedule_redraw(window); +} + +static void +idle_resize(struct task *task, uint32_t events) +{ + struct window *window = + container_of(task, struct window, resize_task); + + window_resize(window, + window->allocation.width, window->allocation.height); + window->resize_scheduled = 0; +} + +void +window_schedule_resize(struct window *window, int width, int height) +{ + if (!window->resize_scheduled) { + window->allocation.width = width; + window->allocation.height = height; + window->resize_task.run = idle_resize; + display_defer(window->display, &window->resize_task); + window->resize_scheduled = 1; + } +} + +static void handle_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t time, uint32_t edges, int32_t width, int32_t height) { struct window *window = data; - struct widget *widget; - int32_t child_width, child_height; - /* FIXME: this is probably the wrong place to check for width - * or height <= 0, but it prevents the compositor from crashing - */ if (width <= 0 || height <= 0) return; window->resize_edges = edges; - if (window->resize_handler) { - child_width = width - 20 - window->margin * 2; - child_height = height - 60 - window->margin * 2; - - (*window->resize_handler)(window, - child_width, child_height, - window->user_data); - } else { - window->allocation.width = width; - window->allocation.height = height; - - if (window->redraw_handler) - window_schedule_redraw(window); - } - - wl_list_for_each(widget, &window->widget_list, link) - widget->allocation = window->allocation; + window_resize(window, width, height); } static void @@ -1954,12 +2008,14 @@ 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); - window->redraw_handler(window, window->user_data); + wl_list_for_each_reverse(widget, &window->widget_list, link) + widget->redraw_handler(widget, widget->user_data); window_flush(window); @@ -2006,7 +2062,7 @@ window_set_fullscreen(struct window *window, int fullscreen) window->decoration = 1; } - (*window->resize_handler)(window, width, height, window->user_data); + window_resize(window, width, height); } void @@ -2028,20 +2084,6 @@ window_get_user_data(struct window *window) } void -window_set_resize_handler(struct window *window, - window_resize_handler_t handler) -{ - window->resize_handler = handler; -} - -void -window_set_redraw_handler(struct window *window, - window_redraw_handler_t handler) -{ - window->redraw_handler = handler; -} - -void window_set_key_handler(struct window *window, window_key_handler_t handler) { @@ -2246,12 +2288,13 @@ menu_button_handler(struct widget *widget, } static void -menu_redraw_handler(struct window *window, void *data) +menu_redraw_handler(struct widget *widget, void *data) { cairo_t *cr; const int32_t r = 3, margin = 3; struct menu *menu = data; int32_t width, height, i; + struct window *window = widget->window; cr = cairo_create(window->cairo_surface); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); @@ -2319,9 +2362,7 @@ window_create_menu(struct display *display, window->parent->shell_surface, window->x, window->y, 0); - window_set_redraw_handler(window, menu_redraw_handler); - window_set_user_data(window, menu); - + widget_set_redraw_handler(menu->widget, menu_redraw_handler); widget_set_enter_handler(menu->widget, menu_enter_handler); widget_set_leave_handler(menu->widget, menu_leave_handler); widget_set_motion_handler(menu->widget, menu_motion_handler); diff --git a/clients/window.h b/clients/window.h index c50c0da..6d35d66 100644 --- a/clients/window.h +++ b/clients/window.h @@ -156,11 +156,6 @@ enum pointer_type { POINTER_HAND1, }; -typedef void (*window_resize_handler_t)(struct window *window, - int32_t width, int32_t height, - void *data); -typedef void (*window_redraw_handler_t)(struct window *window, void *data); - typedef void (*window_key_handler_t)(struct window *window, struct input *input, uint32_t time, uint32_t key, uint32_t unicode, uint32_t state, void *data); @@ -180,6 +175,11 @@ typedef void (*window_drop_handler_t)(struct window *window, typedef void (*window_close_handler_t)(struct window *window, void *data); +typedef void (*widget_resize_handler_t)(struct widget *widget, + int32_t width, int32_t height, + void *data); +typedef void (*widget_redraw_handler_t)(struct widget *widget, void *data); + typedef int (*widget_enter_handler_t)(struct widget *widget, struct input *input, uint32_t time, int32_t x, int32_t y, void *data); @@ -250,6 +250,8 @@ void window_set_child_size(struct window *window, int32_t width, int32_t height); void window_schedule_redraw(struct window *window); +void +window_schedule_resize(struct window *window, int width, int height); void window_damage(struct window *window, int32_t x, int32_t y, @@ -299,17 +301,9 @@ void * window_get_user_data(struct window *window); void -window_set_redraw_handler(struct window *window, - window_redraw_handler_t handler); - -void window_set_decoration(struct window *window, int decoration); void -window_set_resize_handler(struct window *window, - window_resize_handler_t handler); - -void window_set_key_handler(struct window *window, window_key_handler_t handler); @@ -346,6 +340,12 @@ void * widget_get_user_data(struct widget *widget); void +widget_set_redraw_handler(struct widget *widget, + widget_redraw_handler_t handler); +void +widget_set_resize_handler(struct widget *widget, + widget_resize_handler_t handler); +void widget_set_enter_handler(struct widget *widget, widget_enter_handler_t handler); void |