summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/effects.c42
-rw-r--r--src/core/effects.h1
-rw-r--r--src/core/window-private.h4
-rw-r--r--src/core/window.c183
4 files changed, 147 insertions, 83 deletions
diff --git a/src/core/effects.c b/src/core/effects.c
index 4e9b3ae8..853d5ce9 100644
--- a/src/core/effects.c
+++ b/src/core/effects.c
@@ -67,6 +67,7 @@
#endif
#define META_MINIMIZE_ANIMATION_LENGTH 0.25
+#define META_UNMINIMIZE_ANIMATION_LENGTH 0.25
#define META_SHADE_ANIMATION_LENGTH 0.2
#include <string.h>
@@ -98,6 +99,9 @@ typedef struct
MetaRectangle start_rect;
MetaRectangle end_rect;
+ MetaEffectFinished finished;
+ gpointer finished_data;
+
} BoxAnimationContext;
/**
@@ -149,7 +153,9 @@ static void
draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
- double seconds_duration);
+ double seconds_duration,
+ MetaEffectFinished finished,
+ gpointer finished_data);
/**
* Creates an effect.
@@ -173,17 +179,13 @@ create_effect (MetaEffectType type,
}
/**
- * Destroys an effect. If the effect has a "finished" hook, it will be
- * called before cleanup.
+ * Destroys an effect.
*
* \param effect The effect.
*/
static void
effect_free (MetaEffect *effect)
{
- if (effect->priv->finished)
- effect->priv->finished (effect->priv->finished_data);
-
g_free (effect->priv);
g_free (effect);
}
@@ -383,6 +385,8 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
graphics_sync (context);
+ context->finished(context->finished_data);
+
g_free (context);
return FALSE;
}
@@ -430,7 +434,9 @@ void
draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
- double seconds_duration)
+ double seconds_duration,
+ MetaEffectFinished finished,
+ gpointer finished_data)
{
BoxAnimationContext *context;
@@ -455,6 +461,9 @@ draw_box_animation (MetaScreen *screen,
context->start_rect = *initial_rect;
context->end_rect = *destination_rect;
+ context->finished = finished;
+ context->finished_data = finished_data;
+
#ifdef HAVE_SHAPE
attrs.override_redirect = True;
@@ -717,7 +726,17 @@ run_default_effect_handler (MetaEffect *effect)
draw_box_animation (effect->window->screen,
&(effect->u.minimize.window_rect),
&(effect->u.minimize.icon_rect),
- META_MINIMIZE_ANIMATION_LENGTH);
+ META_MINIMIZE_ANIMATION_LENGTH,
+ effect->priv->finished,
+ effect->priv->finished_data);
+ break;
+ case META_EFFECT_UNMINIMIZE:
+ draw_box_animation (effect->window->screen,
+ &(effect->u.minimize.icon_rect),
+ &(effect->u.minimize.window_rect),
+ META_UNMINIMIZE_ANIMATION_LENGTH,
+ effect->priv->finished,
+ effect->priv->finished_data);
break;
default:
@@ -728,8 +747,15 @@ run_default_effect_handler (MetaEffect *effect)
static void
run_handler (MetaEffect *effect)
{
+ /* If effects are disabled just run the finished function */
if (meta_prefs_get_mate_animations ())
+ {
run_default_effect_handler (effect);
+ }
+ else
+ {
+ effect->priv->finished(effect->priv->finished_data);
+ }
effect_free (effect);
}
diff --git a/src/core/effects.h b/src/core/effects.h
index ca25aa88..e0025ff6 100644
--- a/src/core/effects.h
+++ b/src/core/effects.h
@@ -50,6 +50,7 @@
typedef enum
{
+ META_EFFECT_NONE = 0,
META_EFFECT_MINIMIZE,
META_EFFECT_UNMINIMIZE,
META_EFFECT_FOCUS,
diff --git a/src/core/window-private.h b/src/core/window-private.h
index dcb19d7f..65359e15 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -36,6 +36,7 @@
#include <config.h>
#include "window.h"
+#include "effects.h"
#include "screen-private.h"
#include "util.h"
#include "stack.h"
@@ -185,6 +186,9 @@ struct _MetaWindow
guint was_minimized : 1;
guint tab_unminimized : 1;
+ /* Whether there is a pending effect */
+ MetaEffectType effect_pending;
+
/* Whether the window is mapped; actual server-side state
* see also unmaps_pending
*/
diff --git a/src/core/window.c b/src/core/window.c
index 74e69074..694ba99e 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -476,6 +476,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->minimized = FALSE;
window->was_minimized = FALSE;
window->tab_unminimized = FALSE;
+ window->effect_pending = META_EFFECT_NONE;
window->iconic = FALSE;
window->mapped = attrs->map_state != IsUnmapped;
/* if already mapped, no need to worry about focus-on-first-time-showing */
@@ -1452,80 +1453,119 @@ static void
finish_minimize (gpointer data)
{
MetaWindow *window = data;
- /* FIXME: It really sucks to put timestamp pinging here; it'd
- * probably make more sense in implement_showing() so that it's at
- * least not duplicated in meta_window_show; but since
- * finish_minimize is a callback making things just slightly icky, I
- * haven't done that yet.
- */
- guint32 timestamp = meta_display_get_current_time_roundtrip (window->display);
- meta_window_hide (window);
- if (window->has_focus)
- {
- meta_workspace_focus_default_window (window->screen->active_workspace,
- window,
- timestamp);
- }
+ window->effect_pending = META_EFFECT_NONE;
}
static void
-implement_showing (MetaWindow *window,
- gboolean showing)
+finish_unminimize (gpointer data)
{
- /* Actually show/hide the window */
- meta_verbose ("Implement showing = %d for window %s\n",
- showing, window->desc);
+ MetaWindow *window = data;
- if (!showing)
+ meta_window_show (window);
+ window->was_minimized = FALSE;
+ window->effect_pending = META_EFFECT_NONE;
+}
+
+static void
+meta_window_animate_minimize (MetaWindow *window)
+{
+ MetaRectangle icon_rect, window_rect;
+ gboolean result;
+
+ /* Check if the window has an icon geometry */
+ result = meta_window_get_icon_geometry (window, &icon_rect);
+
+ if (!result)
{
- gboolean on_workspace;
+ /* just animate into the corner somehow - maybe
+ * not a good idea...
+ */
+ icon_rect.x = window->screen->rect.width;
+ icon_rect.y = window->screen->rect.height;
+ icon_rect.width = 1;
+ icon_rect.height = 1;
+ }
- on_workspace = meta_window_located_on_workspace (window,
- window->screen->active_workspace);
+ meta_window_get_outer_rect (window, &window_rect);
- /* Really this effects code should probably
- * be in meta_window_hide so the window->mapped
- * test isn't duplicated here. Anyhow, we animate
- * if we are mapped now, we are supposed to
- * be minimized, and we are on the current workspace.
+ meta_effect_run_minimize (window,
+ &window_rect,
+ &icon_rect,
+ finish_minimize,
+ window);
+}
+
+static void
+meta_window_animate_unminimize (MetaWindow *window)
+{
+ MetaRectangle icon_rect, window_rect;
+ gboolean result;
+
+ /* Check if the window has an icon geometry */
+ result = meta_window_get_icon_geometry (window, &icon_rect);
+
+ if (!result)
+ {
+ /* just animate into the corner somehow - maybe
+ * not a good idea...
*/
- if (on_workspace && window->minimized && window->mapped &&
- !meta_prefs_get_reduced_resources ())
- {
- MetaRectangle icon_rect, window_rect;
- gboolean result;
+ icon_rect.x = window->screen->rect.width;
+ icon_rect.y = window->screen->rect.height;
+ icon_rect.width = 1;
+ icon_rect.height = 1;
+ }
- /* Check if the window has an icon geometry */
- result = meta_window_get_icon_geometry (window, &icon_rect);
+ meta_window_get_outer_rect (window, &window_rect);
- if (!result)
- {
- /* just animate into the corner somehow - maybe
- * not a good idea...
- */
- icon_rect.x = window->screen->rect.width;
- icon_rect.y = window->screen->rect.height;
- icon_rect.width = 1;
- icon_rect.height = 1;
- }
+ meta_effect_run_unminimize (window,
+ &window_rect,
+ &icon_rect,
+ finish_unminimize,
+ window);
+}
- meta_window_get_outer_rect (window, &window_rect);
+static void
+implement_showing (MetaWindow *window,
+ gboolean showing)
+{
+ /* Actually show/hide the window */
+ meta_verbose ("Implement showing = %d for window %s with effect pending %i\n",
+ showing, window->desc, window->effect_pending);
- meta_effect_run_minimize (window,
- &window_rect,
- &icon_rect,
- finish_minimize,
- window);
- }
- else
- {
- finish_minimize (window);
- }
+ if (!showing)
+ {
+ /* Handle pending effects */
+ switch(window->effect_pending)
+ {
+ case META_EFFECT_MINIMIZE:
+ /* First hide the window and then animate */
+ meta_window_hide(window);
+ meta_window_animate_minimize (window);
+ break;
+ case META_EFFECT_UNMINIMIZE:
+ case META_EFFECT_NONE:
+ default:
+ meta_window_hide(window);
+ break;
+ }
}
else
{
- meta_window_show (window);
+ /* Handle pending effects */
+ switch(window->effect_pending)
+ {
+ case META_EFFECT_MINIMIZE:
+ break;
+ case META_EFFECT_UNMINIMIZE:
+ /* First animate then show the window */
+ meta_window_animate_unminimize (window);
+ break;
+ case META_EFFECT_NONE:
+ default:
+ meta_window_show (window);
+ break;
+ }
}
}
@@ -2283,24 +2323,6 @@ meta_window_show (MetaWindow *window)
XMapWindow (window->display->xdisplay, window->xwindow);
meta_error_trap_pop (window->display, FALSE);
did_show = TRUE;
-
- if (window->was_minimized)
- {
- MetaRectangle window_rect;
- MetaRectangle icon_rect;
-
- window->was_minimized = FALSE;
-
- if (meta_window_get_icon_geometry (window, &icon_rect))
- {
- meta_window_get_outer_rect (window, &window_rect);
-
- meta_effect_run_unminimize (window,
- &window_rect,
- &icon_rect,
- NULL, NULL);
- }
- }
}
if (window->iconic)
@@ -2332,6 +2354,10 @@ meta_window_show (MetaWindow *window)
meta_display_increment_focus_sentinel (window->display);
}
}
+ else if (window->was_minimized)
+ {
+ meta_window_focus(window, timestamp);
+ }
set_net_wm_state (window);
@@ -2418,6 +2444,8 @@ meta_window_minimize (MetaWindow *window)
if (!window->minimized)
{
window->minimized = TRUE;
+ /* Flag minimize effect pending */
+ window->effect_pending = META_EFFECT_MINIMIZE;
meta_window_queue(window, META_QUEUE_CALC_SHOWING);
meta_window_foreach_transient (window,
@@ -2437,6 +2465,8 @@ meta_window_minimize (MetaWindow *window)
window->desc);
}
}
+
+ /* Should insert minimize effect here? */
}
void
@@ -2446,12 +2476,15 @@ meta_window_unminimize (MetaWindow *window)
{
window->minimized = FALSE;
window->was_minimized = TRUE;
+ window->effect_pending = META_EFFECT_UNMINIMIZE;
meta_window_queue(window, META_QUEUE_CALC_SHOWING);
meta_window_foreach_transient (window,
queue_calc_showing_func,
NULL);
}
+
+ /* Should insert unminimize effect here? */
}
static void