diff --git a/ChangeLog b/ChangeLog index 1684fa8f7..738cdb84d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-05-25 Adam Jackson + + * src/c-window.c: + * src/c-window.h: + * src/compositor.c: + * src/compositor.h: + * src/effects.c: + * src/effects.h: + * src/spring-model.c: + * src/window.c: + Bounce on window focus. + Wed May 24 22:15:01 2006 Søren Sandmann * src/compositor.c (do_effect): Make sure windows are kept on top diff --git a/src/c-window.c b/src/c-window.c index c1988c26e..8da6efebd 100644 --- a/src/c-window.c +++ b/src/c-window.c @@ -34,6 +34,7 @@ #include "c-window.h" #include "window.h" #include "frame.h" +#include "spring-model.h" struct _MetaCompWindow { @@ -1093,6 +1094,72 @@ meta_comp_window_run_minimize (MetaCompWindow *window, g_idle_add (run_animation_01, info); } +/* bounce effect */ + +typedef struct +{ + MetaEffect *effect; + MetaCompWindow *window; + GTimer *timer; + Model *model; + MetaRectangle rect; + gdouble last_time; +} BounceInfo; + +/* XXX HATE */ +extern void get_patch_points (Model *model, CmPoint points[4][4]); +extern void compute_window_rect (MetaWindow *window, MetaRectangle *rect); + +static gboolean +update_bounce (gpointer data) +{ + BounceInfo *info = data; + CmDrawableNode *node = (CmDrawableNode *)info->window->node; + gdouble elapsed = g_timer_elapsed (info->timer, NULL); + int i; + int n_steps = floor ((elapsed - info->last_time) * 60); + CmPoint points[4][4]; + + if (model_is_calm (info->model) || elapsed > 0.7) + { + cm_drawable_node_unset_patch (node); + meta_effect_end (info->effect); + g_free(info); + return FALSE; + } + + for (i = 0; i < n_steps; ++i) + model_step (info->model); + + if (i > 0) + info->last_time = elapsed; + + get_patch_points (info->model, points); + + cm_drawable_node_set_patch (node, points); + return TRUE; +} + +void +meta_comp_window_bounce (MetaCompWindow *comp_window, + MetaEffect *effect) +{ + BounceInfo *info = g_new0 (BounceInfo, 1); + MetaWindow *meta_window = + meta_display_lookup_x_window (comp_window->display, + WS_RESOURCE_XID (comp_window->drawable)); + + info->window = comp_window; + info->effect = effect; + info->timer = g_timer_new (); + info->last_time = 0; + + compute_window_rect (meta_window, &info->rect); + info->model = model_new (&info->rect, TRUE); + + g_idle_add (update_bounce, info); +} + #endif #if 0 diff --git a/src/c-window.h b/src/c-window.h index 099b208b8..00226c868 100644 --- a/src/c-window.h +++ b/src/c-window.h @@ -45,6 +45,8 @@ void meta_comp_window_shrink (MetaCompWindow *comp_window, MetaEffect *effect); void meta_comp_window_unshrink (MetaCompWindow *comp_window, MetaEffect *effect); +void meta_comp_window_bounce (MetaCompWindow *comp_window, + MetaEffect *effect); void meta_comp_window_restack (MetaCompWindow *comp_window, MetaCompWindow *above); void meta_comp_window_freeze_stack (MetaCompWindow *comp_window); diff --git a/src/compositor.c b/src/compositor.c index 46fa983ff..a3ce77a79 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -149,6 +149,15 @@ do_effect (MetaEffect *effect, break; } #endif + case META_EFFECT_FOCUS: + { + MetaCompScreen *screen = meta_comp_screen_get_by_xwindow ( + get_xid (effect->u.focus.window)); + MetaCompWindow *window = meta_comp_screen_lookup_window ( + screen, effect->u.focus.window->frame->xwindow); + meta_comp_window_bounce (window, effect); + break; + } case META_EFFECT_CLOSE: { MetaCompScreen *screen = meta_comp_screen_get_by_xwindow ( @@ -780,7 +789,7 @@ struct MoveInfo #ifdef HAVE_COMPOSITE_EXTENSIONS -static void +void get_patch_points (Model *model, CmPoint points[4][4]) { @@ -850,7 +859,7 @@ wobble (gpointer data) #endif -static void +void compute_window_rect (MetaWindow *window, MetaRectangle *rect) { diff --git a/src/compositor.h b/src/compositor.h index 5fac333dc..7358d922f 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -27,6 +27,9 @@ typedef void (* MetaAnimationFinishedFunc) (gpointer data); +/* XXX namespace me */ +void compute_window_rect (MetaWindow *window, MetaRectangle *rect); + MetaCompositor* meta_compositor_new (MetaDisplay *display); void meta_compositor_unref (MetaCompositor *compositor); void meta_compositor_process_event (MetaCompositor *compositor, diff --git a/src/effects.c b/src/effects.c index c43fc4ac4..ed9c5b6ef 100644 --- a/src/effects.c +++ b/src/effects.c @@ -125,6 +125,21 @@ meta_effect_end (MetaEffect *effect) g_free (effect); } +void +meta_effect_run_focus (MetaWindow *window, + MetaEffectFinished finished, + gpointer data) +{ + MetaEffect *effect; + + g_return_if_fail (window != NULL); + + effect = create_effect (META_EFFECT_FOCUS, finished, data); + effect->u.focus.window = window; + + run_handler (effect); +} + void meta_effect_run_minimize (MetaWindow *window, MetaRectangle *window_rect, diff --git a/src/effects.h b/src/effects.h index 3c4cff917..b4327b331 100644 --- a/src/effects.h +++ b/src/effects.h @@ -66,12 +66,12 @@ typedef struct MetaWindow *window; MetaRectangle window_rect; MetaRectangle icon_rect; -} MetaMinimizeEffect, MetaRestoreEffect; /* same data for both */ +} MetaMinimizeEffect, MetaRestoreEffect; typedef struct { MetaWindow *window; -} MetaCloseEffect; +} MetaCloseEffect, MetaFocusEffect; struct MetaEffect { @@ -83,6 +83,7 @@ struct MetaEffect MetaMinimizeEffect minimize; MetaRestoreEffect restore; MetaCloseEffect close; + MetaFocusEffect focus; } u; MetaEffectPriv *priv; @@ -100,6 +101,9 @@ void meta_effect_run_minimize (MetaWindow *window, void meta_effect_run_close (MetaWindow *window, MetaEffectFinished finished, gpointer data); +void meta_effect_run_focus (MetaWindow *window, + MetaEffectFinished finished, + gpointer data); void meta_effect_end (MetaEffect *effect); diff --git a/src/spring-model.c b/src/spring-model.c index 406a0e4fe..88534dfae 100644 --- a/src/spring-model.c +++ b/src/spring-model.c @@ -205,15 +205,32 @@ model_init_grid (Model *model, MetaRectangle *rect, gboolean expand) hpad = rect->width / 6; vpad = rect->height / 6; } + +#define EXPAND_DELTA 4 for (y = 0; y < GRID_HEIGHT; y++) for (x = 0; x < GRID_WIDTH; x++) { -#if 0 - v_x = 40 * g_random_double() - 20; - v_y = 40 * g_random_double() - 20; -#endif - v_x = v_y = 0; + if (expand) + { + if (y == 0) + v_y = - EXPAND_DELTA * g_random_double(); + else if (y == GRID_HEIGHT - 1) + v_y = EXPAND_DELTA * g_random_double(); + else + v_y = 2 * EXPAND_DELTA * g_random_double() - EXPAND_DELTA; + + if (x == 0) + v_x = - EXPAND_DELTA * g_random_double(); + else if (x == GRID_WIDTH - 1) + v_x = EXPAND_DELTA * g_random_double(); + else + v_x = 2 * EXPAND_DELTA * g_random_double() - EXPAND_DELTA; + } + else + { + v_x = v_y = 0; + } #if 0 if (expand) @@ -355,7 +372,7 @@ on_end_move (Model *model) } } -#define EPSILON 0.01 +#define EPSILON 0.02 gboolean model_is_calm (Model *model) diff --git a/src/window.c b/src/window.c index 732ab2c24..6d5f8edc2 100644 --- a/src/window.c +++ b/src/window.c @@ -42,6 +42,7 @@ #include "window-props.h" #include "constraints.h" #include "compositor.h" +#include "effects.h" #include #include @@ -3760,6 +3761,8 @@ meta_window_focus (MetaWindow *window, if (window->wm_state_demands_attention) meta_window_unset_demands_attention(window); + + meta_effect_run_focus(window, NULL, NULL); } static void