summaryrefslogtreecommitdiff
path: root/clients
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-01-10 12:23:19 -0500
committerKristian Høgsberg <krh@bitplanet.net>2012-01-10 14:22:10 -0500
commitb67e94b17083e014085c582ebb4b691aa700ea5e (patch)
tree29730dca72f0b68510500cd59ff22783ab6569b4 /clients
parent5d12990dbecea205f095a17d02fdb952ba22cf13 (diff)
window: Make resize and redraw handlers widget vfuncs
Diffstat (limited to 'clients')
-rw-r--r--clients/desktop-shell.c133
-rw-r--r--clients/dnd.c15
-rw-r--r--clients/eventdemo.c35
-rw-r--r--clients/flower.c35
-rw-r--r--clients/gears.c19
-rw-r--r--clients/image.c15
-rw-r--r--clients/resizor.c13
-rw-r--r--clients/tablet-shell.c3
-rw-r--r--clients/terminal.c23
-rw-r--r--clients/view.c12
-rw-r--r--clients/window.c129
-rw-r--r--clients/window.h26
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