[PATCH weston 5/9] shell: Implement simple dnd for window list item reordering
Scott Moreau
oreaus at gmail.com
Thu Mar 7 20:47:14 PST 2013
This allows the user to rearrange the list items by drag-and-drop. There is no
drag icon, only preliminary functionality. Eventually, this could be expanded
to use the wayland dnd protocol.
---
clients/desktop-shell.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 582a19f..1fa7387 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -122,8 +122,10 @@ struct list_item {
struct panel *panel;
cairo_surface_t *icon;
int focused, highlight;
+ int x, y;
struct wl_list link;
struct wl_list surface_link;
+ struct wl_list reorder_link;
};
struct panel_launcher {
@@ -1145,6 +1147,9 @@ panel_list_item_motion_handler(struct widget *widget, struct input *input,
{
struct list_item *item = data;
+ item->x = x;
+ item->y = y;
+
widget_set_tooltip(widget, basename((char *)item->surface->title), x, y);
return CURSOR_LEFT_PTR;
@@ -1156,6 +1161,8 @@ panel_list_item_enter_handler(struct widget *widget, struct input *input,
{
struct list_item *item = data;
+ item->x = x;
+ item->y = y;
item->highlight = 1;
item->focused = 1;
widget_schedule_redraw(widget);
@@ -1243,6 +1250,79 @@ list_item_show_menu(struct list_item *item, struct input *input, uint32_t time)
list_item_menu_func, entries, MENU_ENTRIES);
}
+static int
+rect_contains_point(struct rectangle rect, int x, int y)
+{
+ int x1, y1, x2, y2;
+
+ x1 = rect.x;
+ y1 = rect.y;
+ x2 = rect.x + rect.width;
+ y2 = rect.y + rect.height;
+
+ if (x > x1 && x < x2 && y > y1 && y < y2)
+ return 1;
+
+ return 0;
+}
+
+static int
+item_contains_point(struct list_item *item, int x, int y)
+{
+ struct rectangle item_rect;
+
+ widget_get_allocation(item->widget, &item_rect);
+
+ return rect_contains_point(item_rect, x, y);
+}
+
+static int
+list_contains_point(struct list_item *item, int x, int y)
+{
+ struct rectangle list_rect;
+
+ list_rect = item->panel->window_list_rect;
+
+ return rect_contains_point(list_rect, x, y);
+}
+
+static void
+panel_item_list_reorder(struct panel *panel,
+ struct list_item *current, struct list_item *item)
+{
+ struct rectangle current_rect, item_rect;
+
+ if (current == item)
+ return;
+
+ widget_get_allocation(current->widget, ¤t_rect);
+ widget_get_allocation(item->widget, &item_rect);
+
+ wl_list_remove(¤t->link);
+
+ if (item_rect.x < current_rect.x)
+ wl_list_insert(item->link.prev, ¤t->link);
+ else
+ wl_list_insert(&item->link, ¤t->link);
+
+ panel_window_list_schedule_redraw(item->panel);
+}
+
+static void
+list_item_move(struct list_item *current, int x, int y)
+{
+ struct list_item *item;
+
+ wl_list_for_each(item, ¤t->panel->window_list, link) {
+ if (item == current)
+ continue;
+ if (item_contains_point(item, x, y)) {
+ panel_item_list_reorder(item->panel, current, item);
+ return;
+ }
+ }
+}
+
static void
panel_list_item_button_handler(struct widget *widget,
struct input *input, uint32_t time,
@@ -1267,6 +1347,11 @@ panel_list_item_button_handler(struct widget *widget,
return;
surface = item->surface;
+ if (!item_contains_point(item, item->x, item->y)) {
+ if (list_contains_point(item, item->x, item->y))
+ list_item_move(item, item->x, item->y);
+ return;
+ }
if (!surface->focused && !surface->minimized) {
surface_data_focus(surface->surface_data);
surface->focused = 1;
--
1.7.10.4
More information about the wayland-devel
mailing list