[PATCH 4/6 weston] clients: desktop-shell: show tooltip for panel items
Tiago Vignatti
tiago.vignatti at intel.com
Mon May 21 06:47:48 PDT 2012
A timer is set whenever there's pointer motion inside a panel launcher item;
if the pointer stills inside the item after stopped for 500ms, then tooltip
shows up.
Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
clients/desktop-shell.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 7554df3..19b644e 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -31,6 +31,9 @@
#include <cairo.h>
#include <sys/wait.h>
#include <linux/input.h>
+#include <sys/timerfd.h>
+#include <sys/epoll.h>
+#include <libgen.h>
#include <wayland-client.h>
#include "window.h"
@@ -82,6 +85,10 @@ struct panel_launcher {
int focused, pressed;
const char *path;
struct wl_list link;
+
+ struct task tooltip_task;
+ int tooltip_fd;
+ float last_x, last_y;
};
struct unlock_dialog {
@@ -248,7 +255,9 @@ panel_launcher_leave_handler(struct widget *widget,
struct input *input, void *data)
{
struct panel_launcher *launcher = data;
+ struct window *parent = launcher->panel->window;
+ window_destroy_tooltip(parent);
launcher->focused = 0;
widget_schedule_redraw(widget);
}
@@ -267,6 +276,74 @@ panel_launcher_button_handler(struct widget *widget,
}
static void
+tooltip_func(struct task *task, uint32_t events)
+{
+ struct panel_launcher *launcher =
+ container_of(task, struct panel_launcher, tooltip_task);
+ uint64_t exp;
+ struct window *parent = launcher->panel->window;
+ const int offset_y = 27;
+
+ read(launcher->tooltip_fd, &exp, sizeof (uint64_t));
+
+ if (launcher->focused)
+ window_create_tooltip(parent, launcher->last_x,
+ launcher->last_y + offset_y,
+ basename((char *)launcher->path));
+}
+
+#define TOOLTIP_TIMEOUT 500
+static int
+tooltip_timer_reset(struct panel_launcher *launcher)
+{
+ struct itimerspec its;
+
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = TOOLTIP_TIMEOUT / 1000;
+ its.it_value.tv_nsec = (TOOLTIP_TIMEOUT % 1000) * 1000 * 1000;
+ if (timerfd_settime(launcher->tooltip_fd, 0, &its, NULL) < 0) {
+ fprintf(stderr, "could not set timerfd\n: %m");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+tooltip_timer_create(struct display *display, struct panel_launcher *launcher)
+{
+ /* FIXME: fd here is never closed anywhere; maybe we need a
+ * panel_launcher_destroy for such. */
+ launcher->tooltip_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+ if (launcher->tooltip_fd < 0) {
+ fprintf(stderr, "could not create timerfd\n: %m");
+ return -1;
+ }
+
+ launcher->tooltip_task.run = tooltip_func;
+ display_watch_fd(display, launcher->tooltip_fd, EPOLLIN,
+ &launcher->tooltip_task);
+
+ tooltip_timer_reset(launcher);
+ return 0;
+}
+
+static int
+panel_launcher_motion_handler(struct widget *widget,
+ struct input *input, uint32_t time,
+ float x, float y, void *data)
+{
+ struct panel_launcher *launcher = data;
+
+ tooltip_timer_reset(launcher);
+ launcher->last_x = x;
+ launcher->last_y = y;
+
+ return POINTER_LEFT_PTR;
+}
+
+static void
panel_button_handler(struct widget *widget,
struct input *input, uint32_t time,
uint32_t button, uint32_t state, void *data)
@@ -353,6 +430,10 @@ panel_add_launcher(struct panel *panel, const char *icon, const char *path)
panel_launcher_button_handler);
widget_set_redraw_handler(launcher->widget,
panel_launcher_redraw_handler);
+ widget_set_motion_handler(launcher->widget,
+ panel_launcher_motion_handler);
+
+ tooltip_timer_create(window_get_display(panel->window), launcher);
}
enum {
--
1.7.9.5
More information about the wayland-devel
mailing list