[PATCH 2/3] window: add simple text tooltip handlers

Tiago Vignatti tiago.vignatti at linux.intel.com
Fri May 25 01:30:04 PDT 2012


On 05/23/2012 10:06 PM, Tiago Vignatti wrote:
> Using set_transient.
>
> Signed-off-by: Tiago Vignatti<tiago.vignatti at intel.com>
> ---
>   clients/window.c |  188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   clients/window.h |    7 ++
>   2 files changed, 195 insertions(+)
>
> diff --git a/clients/window.c b/clients/window.c
> index 489c35a..9e9b209 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -36,6 +36,7 @@
>   #include<cairo.h>
>   #include<sys/mman.h>
>   #include<sys/epoll.h>
> +#include<sys/timerfd.h>
>
>   #include<pixman.h>
>
> @@ -169,6 +170,7 @@ struct window {
>
>   struct widget {
>   	struct window *window;
> +	struct tooltip *tooltip;
>   	struct wl_list child_list;
>   	struct wl_list link;
>   	struct rectangle allocation;
> @@ -180,6 +182,7 @@ struct widget {
>   	widget_button_handler_t button_handler;
>   	void *user_data;
>   	int opaque;
> +	int tooltip_count;
>   };
>
>   struct input {
> @@ -266,6 +269,16 @@ struct menu {
>   	menu_func_t func;
>   };
>
> +struct tooltip {
> +	struct widget *parent;
> +	struct window *window;
> +	struct widget *widget;
> +	char *entry;
> +	struct task tooltip_task;
> +	int tooltip_fd;
> +	float x, y;
> +};
> +
>   struct shm_pool {
>   	struct wl_shm_pool *pool;
>   	size_t size;
> @@ -862,6 +875,8 @@ widget_create(struct window *window, void *data)
>   	widget->allocation = window->allocation;
>   	wl_list_init(&widget->child_list);
>   	widget->opaque = 0;
> +	widget->tooltip = NULL;
> +	widget->tooltip_count = 0;
>
>   	return widget;
>   }
> @@ -892,6 +907,11 @@ widget_destroy(struct widget *widget)
>   	struct display *display = widget->window->display;
>   	struct input *input;
>
> +	if (widget->tooltip) {
> +		free(widget->tooltip);
> +		widget->tooltip = NULL;
> +	}
> +
>   	wl_list_for_each(input,&display->input_list, link) {
>   		if (input->focus_widget == widget)
>   			input->focus_widget = NULL;
> @@ -1000,6 +1020,174 @@ window_get_wl_shell_surface(struct window *window)
>   }
>
>   static void
> +tooltip_redraw_handler(struct widget *widget, void *data)
> +{
> +	cairo_t *cr;
> +	const int32_t r = 3;
> +	struct tooltip *tooltip = data;
> +	int32_t width, height;
> +	struct window *window = widget->window;
> +
> +	cr = cairo_create(window->cairo_surface);
> +	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
> +	cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
> +	cairo_paint(cr);
> +
> +	width = window->allocation.width;
> +	height = window->allocation.height;
> +	rounded_rect(cr, 0, 0, width, height, r);
> +
> +	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
> +	cairo_set_source_rgba(cr, 0.0, 0.0, 0.4, 0.8);
> +	cairo_fill(cr);
> +
> +	cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
> +	cairo_move_to(cr, 10, 16);
> +	cairo_show_text(cr, tooltip->entry);
> +	cairo_destroy(cr);
> +}
> +
> +static cairo_text_extents_t
> +get_text_extents(struct tooltip *tooltip)
> +{
> +	struct window *window;
> +	cairo_t *cr;
> +	cairo_text_extents_t extents;
> +
> +	/* we borrow cairo_surface from the parent cause tooltip's wasn't
> +	 * created yet */
> +	window = tooltip->widget->window->parent;
> +	cr = cairo_create(window->cairo_surface);
> +	cairo_text_extents(cr, tooltip->entry,&extents);
> +	cairo_destroy(cr);
> +
> +	return extents;
> +}

Ander found a problem (thanks for testing!) with this function when 
cairo is with shm buffer type. In that case, parent's cairo_surface is 
NULL and eventually extents returns a nil value.

I see two alternatives now: (1) create a temporary cairo_surface or (2) 
delay one frame the tooltip creation, get the correct extents using 
tooltip's cairo_surface, and schedule a new resize and redraw handler 
_inside_ the redraw handler. I guess the latter works, but it's more 
code and uglier in my opinion.

Suggestions?

Tiago


More information about the wayland-devel mailing list