Skip to content

Commit

Permalink
* Can now drag-and-drop workspaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
nigel.tao.gnome committed Dec 26, 2006
1 parent 01e0591 commit f84b26f
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 63 deletions.
7 changes: 6 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
2006-12-26 Nigel Tao <[email protected]> revision 12

* Can now drag-and-drop workspaces.


2006-12-25 Nigel Tao <[email protected]> revision 11

* New -c, -v and -? command line options.
-c or --trigger-on-caps-lock makes the Caps Lock key also switch windows.
-c or --trigger-on-caps-lock makes Caps Lock also switch windows.
-v or --version shows the version number and exits.
-? or --help shows a brief instruction guide.

Expand Down
27 changes: 18 additions & 9 deletions src/draganddrop.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ ss_draganddrop_reset (SSDragAndDrop *dnd)
dnd->is_dragging = FALSE;
dnd->drag_start_x = -1;
dnd->drag_start_y = -1;
dnd->drag_start_workspace = NULL;
dnd->drag_start_window = NULL;
dnd->drag_start_workspace = NULL;
dnd->drag_start_widget = NULL;
dnd->drag_x = -1;
dnd->drag_y = -1;
dnd->drag_workspace = NULL;
Expand Down Expand Up @@ -51,10 +52,16 @@ ss_draganddrop_free (SSDragAndDrop *dnd)
//------------------------------------------------------------------------------

void
ss_draganddrop_on_motion (SSDragAndDrop *dnd, int x, int y)
ss_draganddrop_on_motion (SSDragAndDrop *dnd)
{
int x, y;
if (dnd->drag_start_widget == NULL) {
return;
}
gdk_window_get_pointer (dnd->drag_start_widget->window, &x, &y, NULL);

if ((!dnd->is_dragging) &&
(gtk_drag_check_threshold (dnd->drag_start_window->widget,
(gtk_drag_check_threshold (dnd->drag_start_widget,
dnd->drag_start_x, dnd->drag_start_y, x, y))) {

dnd->is_dragging = TRUE;
Expand All @@ -68,7 +75,7 @@ ss_draganddrop_on_motion (SSDragAndDrop *dnd, int x, int y)
ss_workspace_find_index_near_point (
dnd->drag_workspace, x, y);

gtk_widget_queue_draw (gtk_widget_get_toplevel (dnd->drag_workspace->widget));
gtk_widget_queue_draw (gtk_widget_get_toplevel (dnd->drag_start_widget));
} else {
dnd->new_window_index = -1;
}
Expand All @@ -82,7 +89,7 @@ ss_draganddrop_on_release (SSDragAndDrop *dnd)
{
if (dnd->is_dragging) {
if (dnd->drag_workspace != NULL) {
gtk_widget_queue_draw (gtk_widget_get_toplevel (dnd->drag_workspace->widget));
gtk_widget_queue_draw (gtk_widget_get_toplevel (dnd->drag_start_widget));
}
}
ss_draganddrop_reset (dnd);
Expand All @@ -91,10 +98,12 @@ ss_draganddrop_on_release (SSDragAndDrop *dnd)
//------------------------------------------------------------------------------

void
ss_draganddrop_start_from_window (SSDragAndDrop *dnd, SSWindow *window, int x, int y)
ss_draganddrop_start (SSDragAndDrop *dnd, SSWindow *window, SSWorkspace *workspace)
{
dnd->drag_start_x = x;
dnd->drag_start_y = y;
dnd->drag_start_workspace = window->workspace;
dnd->drag_start_window = window;
dnd->drag_start_workspace = workspace;
dnd->drag_start_widget = window ? window->widget : workspace->widget;
gdk_window_get_pointer (dnd->drag_start_widget->window,
&(dnd->drag_start_x),
&(dnd->drag_start_y), NULL);
}
11 changes: 7 additions & 4 deletions src/draganddrop.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define SUPERSWITCHER_DRAGANDDROP_H

#include <glib.h>
#include <gtk/gtk.h>

#include "forward_declarations.h"

Expand All @@ -15,8 +16,9 @@ struct _SSDragAndDrop {

int drag_start_x;
int drag_start_y;
SSWorkspace * drag_start_workspace;
SSWindow * drag_start_window;
SSWorkspace * drag_start_workspace;
GtkWidget * drag_start_widget;

int drag_x;
int drag_y;
Expand All @@ -27,8 +29,9 @@ struct _SSDragAndDrop {
SSDragAndDrop * ss_draganddrop_new (SSScreen *screen);
void ss_draganddrop_free (SSDragAndDrop *dnd);

void ss_draganddrop_on_motion (SSDragAndDrop *dnd, int x, int y);
void ss_draganddrop_on_release (SSDragAndDrop *dnd);
void ss_draganddrop_start_from_window (SSDragAndDrop *dnd, SSWindow *window, int x, int y);
void ss_draganddrop_on_motion (SSDragAndDrop *dnd);
void ss_draganddrop_on_release (SSDragAndDrop *dnd);

void ss_draganddrop_start (SSDragAndDrop *dnd, SSWindow *window, SSWorkspace *workspace);

#endif
70 changes: 41 additions & 29 deletions src/popup.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,20 +550,20 @@ on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
screen = popup->screen;

dnd = screen->drag_and_drop;
if (dnd->is_dragging) {
if (dnd->drag_start_window != NULL && dnd->drag_workspace != NULL) {
// Some contortions just to get the theme color as 0-255 RGB.
colormap = gdk_colormap_get_system ();
gc = widget->style->text_gc[GTK_STATE_NORMAL];
gdk_gc_get_values (gc, &gc_values);
gdk_colormap_query_color (colormap, gc_values.foreground.pixel, &color);
rr = (255 * color.red) / 65535;
gg = (255 * color.green) / 65535;
bb = (255 * color.blue) / 65535;

c = gdk_cairo_create (popup->window->window);
cairo_set_line_width (c, 2.0);

if ((dnd->is_dragging) && (dnd->drag_workspace != NULL)) {
c = gdk_cairo_create (popup->window->window);
cairo_set_line_width (c, 2.0);

// Some contortions just to get the theme color as 0-255 RGB.
colormap = gdk_colormap_get_system ();
gc = widget->style->text_gc[GTK_STATE_NORMAL];
gdk_gc_get_values (gc, &gc_values);
gdk_colormap_query_color (colormap, gc_values.foreground.pixel, &color);
rr = (255 * color.red) / 65535;
gg = (255 * color.green) / 65535;
bb = (255 * color.blue) / 65535;

if (dnd->drag_start_window != NULL) {
a = &(dnd->drag_start_window->widget->allocation);
oldx0 = -3 + a->x;
oldx1 = +3 + a->x + a->width;
Expand All @@ -586,23 +586,35 @@ on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
}
newy0 = -1 + y - oldhalfheight;
newy1 = +1 + y + oldhalfheight;
} else {
a = &(dnd->drag_start_workspace->widget->allocation);
oldx0 = -4 + a->x;
oldx1 = +4 + a->x + a->width;
oldy0 = -2 + a->y;
oldy1 = +2 + a->y + a->height;

cairo_move_to (c, oldx0, oldy0);
cairo_line_to (c, oldx1, oldy0);
cairo_line_to (c, oldx1, oldy1);
cairo_line_to (c, oldx0, oldy1);
cairo_close_path (c);
cairo_set_source_rgba (c, rr, gg, bb, 0.25);
cairo_stroke (c);

cairo_move_to (c, newx0, newy0);
cairo_line_to (c, newx1, newy0);
cairo_line_to (c, newx1, newy1);
cairo_line_to (c, newx0, newy1);
cairo_close_path (c);
cairo_set_source_rgba (c, rr, gg, bb, 0.75);
cairo_stroke (c);
a = &(dnd->drag_workspace->widget->allocation);
newx0 = -4 + a->x;
newx1 = +4 + a->x + a->width;
newy0 = -2 + a->y;
newy1 = +2 + a->y + a->height;
}

cairo_move_to (c, oldx0, oldy0);
cairo_line_to (c, oldx1, oldy0);
cairo_line_to (c, oldx1, oldy1);
cairo_line_to (c, oldx0, oldy1);
cairo_close_path (c);
cairo_set_source_rgba (c, rr, gg, bb, 0.25);
cairo_stroke (c);

cairo_move_to (c, newx0, newy0);
cairo_line_to (c, newx1, newy0);
cairo_line_to (c, newx1, newy1);
cairo_line_to (c, newx0, newy1);
cairo_close_path (c);
cairo_set_source_rgba (c, rr, gg, bb, 0.75);
cairo_stroke (c);
}
#endif
return FALSE;
Expand Down
21 changes: 6 additions & 15 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,10 @@ static gboolean
on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
SSWindow *window;
SSScreen *screen;
int x, y;
SSWorkspace *workspace;
window = (SSWindow *) data;
screen = window->workspace->screen;
gdk_window_get_pointer (window->widget->window, &x, &y, NULL);

ss_draganddrop_start_from_window (screen->drag_and_drop, window, x, y);
workspace = window->workspace;
ss_draganddrop_start (workspace->screen->drag_and_drop, window, workspace);
return TRUE;
}

Expand Down Expand Up @@ -169,11 +166,12 @@ on_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer data
}
ss_window_activate_window (window, event->time, FALSE);
}
ss_draganddrop_on_release (dnd);
} else {
// It's a plain old click, not a drag.
window->new_window_index = -1;
ss_window_activate_workspace_and_window (window, event->time, FALSE);
}
ss_draganddrop_on_release (dnd);
return TRUE;
}

Expand All @@ -182,14 +180,7 @@ on_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer data
static gboolean
on_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
SSWindow *window;
SSScreen *screen;
int x, y;
window = (SSWindow *) data;
screen = window->workspace->screen;
gdk_window_get_pointer (window->widget->window, &x, &y, NULL);

ss_draganddrop_on_motion (screen->drag_and_drop, x, y);
ss_draganddrop_on_motion (((SSWindow *) data)->workspace->screen->drag_and_drop);
return TRUE;
}

Expand Down
65 changes: 60 additions & 5 deletions src/workspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <X11/X.h>

#include "draganddrop.h"
#include "screen.h"
#include "window.h"

Expand Down Expand Up @@ -137,17 +138,62 @@ static gboolean
on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
SSWorkspace *workspace;
workspace = (SSWorkspace *) data;
ss_draganddrop_start (workspace->screen->drag_and_drop, NULL, workspace);
return TRUE;
}

//------------------------------------------------------------------------------

static gboolean
on_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
SSWorkspace *workspace;
SSScreen *screen;
SSDragAndDrop *dnd;
gboolean shifted;
gboolean ctrled;
WnckWorkspace *dest_wnck_workspace;
GList *i;
SSWindow *window;

workspace = (SSWorkspace *) data;
screen = workspace->screen;
dnd = screen->drag_and_drop;

shifted = ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK);
ctrled = ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK);

ss_screen_change_active_workspace_to (workspace->screen,
((SSWorkspace *) data)->wnck_workspace,
shifted, ctrled, event->time);
if (dnd->is_dragging) {
if (dnd->drag_workspace != NULL) {
dest_wnck_workspace = dnd->drag_workspace->wnck_workspace;
// This simple if clause is to avoid unnecessary work.
if (dnd->drag_workspace != workspace) {
for (i = workspace->windows; i; i = i->next) {
window = (SSWindow *) i->data;
wnck_window_move_to_workspace (
window->wnck_window,
dest_wnck_workspace);
}
}
wnck_workspace_activate (dest_wnck_workspace, event->time);
}
} else {
// It's a plain old click, not a drag.
ss_screen_change_active_workspace_to (workspace->screen,
workspace->wnck_workspace, shifted, ctrled, event->time);
}

ss_draganddrop_on_release (dnd);
return TRUE;
}

//------------------------------------------------------------------------------

static gboolean
on_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
ss_draganddrop_on_motion (((SSWorkspace *) data)->screen->drag_and_drop);
return TRUE;
}

Expand Down Expand Up @@ -298,7 +344,11 @@ ss_workspace_new (SSScreen *screen, WnckWorkspace *wnck_workspace)
gtk_container_add (GTK_CONTAINER (align), box);

header = gtk_drawing_area_new ();
gtk_widget_add_events (header, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
gtk_widget_add_events (header,
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_HINT_MASK |
GDK_POINTER_MOTION_MASK);
gtk_widget_set_size_request (header, MINI_WORKSPACE_WIDTH,
MINI_WORKSPACE_WIDTH * screen->screen_aspect);

Expand All @@ -323,10 +373,15 @@ ss_workspace_new (SSScreen *screen, WnckWorkspace *wnck_workspace)
g_signal_connect (G_OBJECT (header), "expose-event",
(GCallback) on_expose_event,
w);
// TODO: button-release-event
g_signal_connect (G_OBJECT (header), "button-press-event",
(GCallback) on_button_press_event,
w);
g_signal_connect (G_OBJECT (header), "button-release-event",
(GCallback) on_button_release_event,
w);
g_signal_connect (G_OBJECT (header), "motion-notify-event",
(GCallback) on_motion_notify_event,
w);
g_signal_connect (G_OBJECT (header), "scroll-event",
(GCallback) on_scroll_event,
w);
Expand Down

0 comments on commit f84b26f

Please sign in to comment.