window: Make resize and redraw handlers widget vfuncs

dev
Kristian Høgsberg 13 years ago
parent 5d12990dbe
commit b67e94b170
  1. 133
      clients/desktop-shell.c
  2. 15
      clients/dnd.c
  3. 35
      clients/eventdemo.c
  4. 35
      clients/flower.c
  5. 19
      clients/gears.c
  6. 15
      clients/image.c
  7. 13
      clients/resizor.c
  8. 3
      clients/tablet-shell.c
  9. 23
      clients/terminal.c
  10. 12
      clients/view.c
  11. 129
      clients/window.c
  12. 26
      clients/window.h

@ -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,13 +259,31 @@ 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,
@ -281,8 +291,10 @@ panel_configure(void *data,
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;
@ -445,14 +465,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);

@ -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;
@ -191,14 +192,6 @@ dnd_draw(struct dnd *dnd)
cairo_surface_destroy(surface);
}
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;
}

@ -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);
@ -121,18 +125,6 @@ eventdemo_draw(struct eventdemo *e) {
cairo_surface_destroy(surface);
}
/**
* \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
@ -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,

@ -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;

@ -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);

@ -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;
@ -176,14 +178,6 @@ image_draw(struct image *image)
cairo_surface_destroy(surface);
}
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);

@ -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;
@ -122,14 +123,6 @@ resizor_draw(struct resizor *resizor)
cairo_surface_destroy(surface);
}
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);

@ -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;

@ -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;
@ -1029,14 +1029,6 @@ resize_handler(struct window *window,
terminal_resize(terminal, width, height);
}
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);
@ -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);

@ -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;

@ -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)
@ -1100,6 +1104,20 @@ widget_get_user_data(struct widget *widget)
return widget->user_data;
}
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)
{
@ -1857,40 +1875,76 @@ window_move(struct window *window, struct input *input, uint32_t time)
input->input_device, 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
@ -2027,20 +2083,6 @@ window_get_user_data(struct window *window)
return window->user_data;
}
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);

@ -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,
@ -298,17 +300,9 @@ window_set_user_data(struct window *window, void *data);
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);
@ -345,6 +339,12 @@ widget_set_allocation(struct widget *widget,
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);

Loading…
Cancel
Save