diff options
-rw-r--r-- | dock.c | 83 |
1 files changed, 69 insertions, 14 deletions
@@ -12,6 +12,7 @@ #include <string.h> #include <sys/time.h> #include <math.h> +#include <limits.h> #include <gconf/gconf-client.h> #include <gdk-pixbuf/gdk-pixbuf.h> @@ -74,6 +75,7 @@ struct _KibaDock int drag_distance; KibaLauncher *dragging_launcher; int dx, dy; + gboolean dragging_dock; GConfClient *gconf_client; }; @@ -141,21 +143,22 @@ typedef struct { GtkOrientation orientation; int halignment; int valignment; + GdkPoint anchor; } KibaDockLayoutData; static const KibaDockLayoutData kiba_dock_layout_data[] = { - { "left-edge-top", GTK_ORIENTATION_VERTICAL, 0, 0 }, - { "left-edge-center", GTK_ORIENTATION_VERTICAL, 0, 1 }, - { "left-edge-bottom", GTK_ORIENTATION_VERTICAL, 0, 2 }, - { "right-edge-top", GTK_ORIENTATION_VERTICAL, 2, 0 }, - { "right-edge-center", GTK_ORIENTATION_VERTICAL, 2, 1 }, - { "right-edge-bottom", GTK_ORIENTATION_VERTICAL, 2, 2 }, - { "top-edge-left", GTK_ORIENTATION_HORIZONTAL, 0, 0 }, - { "top-edge-center", GTK_ORIENTATION_HORIZONTAL, 1, 0 }, - { "top-edge-right", GTK_ORIENTATION_HORIZONTAL, 2, 0 }, - { "bottom-edge-left", GTK_ORIENTATION_HORIZONTAL, 0, 2 }, - { "bottom-edge-center", GTK_ORIENTATION_HORIZONTAL, 1, 2 }, - { "bottom-edge-right", GTK_ORIENTATION_HORIZONTAL, 2, 2 } + { "left-edge-top", GTK_ORIENTATION_VERTICAL, 0, 0, { 0, 1 } }, + { "left-edge-center", GTK_ORIENTATION_VERTICAL, 0, 1, { 0, 2 } }, + { "left-edge-bottom", GTK_ORIENTATION_VERTICAL, 0, 2, { 0, 3 } }, + { "right-edge-top", GTK_ORIENTATION_VERTICAL, 2, 0, { 4, 1 } }, + { "right-edge-center", GTK_ORIENTATION_VERTICAL, 2, 1, { 4, 2 } }, + { "right-edge-bottom", GTK_ORIENTATION_VERTICAL, 2, 2, { 4, 3 } }, + { "top-edge-left", GTK_ORIENTATION_HORIZONTAL, 0, 0, { 1, 0 } }, + { "top-edge-center", GTK_ORIENTATION_HORIZONTAL, 1, 0, { 2, 0 } }, + { "top-edge-right", GTK_ORIENTATION_HORIZONTAL, 2, 0, { 3, 0 } }, + { "bottom-edge-left", GTK_ORIENTATION_HORIZONTAL, 0, 2, { 1, 4 } }, + { "bottom-edge-center", GTK_ORIENTATION_HORIZONTAL, 1, 2, { 2, 4 } }, + { "bottom-edge-right", GTK_ORIENTATION_HORIZONTAL, 2, 2, { 3, 4 } } }; static void @@ -349,7 +352,15 @@ kiba_dock_realize (GtkWidget *widget) attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gdk_screen_get_rgba_visual (screen); attributes.colormap = gdk_screen_get_rgba_colormap (screen); - attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; + attributes.event_mask = gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK; + attributes_mask = GDK_WA_X | GDK_WA_Y; if (attributes.visual != NULL && attributes.colormap != NULL) attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP; @@ -521,6 +532,12 @@ kiba_dock_button_press_event (GtkWidget *widget, dock->drag_offset_y = event->y; dock->drag_distance = 0; + if (widget->window == event->window) + { + dock->dragging_dock = TRUE; + return TRUE; + } + launcher = kiba_dock_get_launcher_for_window (dock, event->window); if (launcher == NULL) return FALSE; @@ -606,6 +623,12 @@ kiba_dock_button_release_event (GtkWidget *widget, { KibaDock *dock = KIBA_DOCK (widget); + if (dock->dragging_dock) + { + dock->dragging_dock = FALSE; + return TRUE; + } + if (dock->dragging_launcher && dock->drag_distance <= 1) g_idle_add (kiba_launcher_exec, dock->dragging_launcher); else @@ -620,15 +643,47 @@ kiba_dock_button_release_event (GtkWidget *widget, return TRUE; } +static int +kiba_dock_find_closest_position (KibaDock *dock, int x, int y) +{ + int i, min_d, d, position; + int dx, dy; + + min_d = INT_MAX; + for (i = 0; i < G_N_ELEMENTS (kiba_dock_layout_data); i++) + { + dx = x - dock->geometry.width * kiba_dock_layout_data[i].anchor.x / 4; + dy = y - dock->geometry.height * kiba_dock_layout_data[i].anchor.y / 4; + d = dx * dx + dy * dy; + if (d < min_d) + { + min_d = d; + position = i; + } + } + + return position; +} + static gboolean kiba_dock_motion_notify_event (GtkWidget *widget, GdkEventMotion *event) { KibaDock *dock = KIBA_DOCK (widget); GdkModifierType state; - int x, y, new_x, new_y, dx, dy; + int x, y, new_x, new_y, dx, dy, position; gdk_window_get_pointer (gdk_get_default_root_window(), &x, &y, &state); + + if (dock->dragging_dock) + { + position = kiba_dock_find_closest_position (dock, x, y); + gconf_client_set_string (dock->gconf_client, + KIBA_GCONF_PATH "/options/position", + kiba_dock_layout_data[position].name, NULL); + return TRUE; + } + new_x = x - dock->drag_offset_x + ICON_SIZE / 2; new_y = y - dock->drag_offset_y + ICON_SIZE / 2; dx = new_x - dock->mouse_anchor->x; |