Beginning of new layer that abstracts transition effects.
Mon May 22 17:35:52 2006 Søren Sandmann <sandmann@redhat.com> * src/effects.[ch]: Beginning of new layer that abstracts transition effects. New functions: (meta_push_effect_handler): Install an effect handler (meta_pop_effect_handler): Remove last effect handler (meta_effect_run_minimize): Create a minimize effect and pass it to the handler. (meta_effect_end): Called by handler when the effect is finished. * src/compositor.c: Move explosion code form there to src/c-window.c. * src/c-screen.c: Delete explosion related code.
This commit is contained in:
parent
cdb94d7e57
commit
3e5b9776c6
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
Mon May 22 17:35:52 2006 Søren Sandmann <sandmann@redhat.com>
|
||||
|
||||
* src/effects.[ch]: Beginning of new layer that abstracts
|
||||
transition effects.
|
||||
|
||||
New functions:
|
||||
(meta_push_effect_handler): Install an effect handler
|
||||
(meta_pop_effect_handler): Remove last effect handler
|
||||
(meta_effect_run_minimize): Create a minimize effect and pass it
|
||||
to the handler.
|
||||
(meta_effect_end): Called by handler when the effect is finished.
|
||||
|
||||
* src/compositor.c: Move explosion code form there to src/c-window.c.
|
||||
|
||||
* src/c-screen.c: Delete explosion related code.
|
||||
|
||||
2006-05-22 Björn Lindqvist <bjourne@gmail.com>
|
||||
|
||||
* common.h (enum MetaCursor):
|
||||
|
@ -64,6 +64,13 @@ meta_comp_window_lookup (MetaCompScreen *info,
|
||||
return window;
|
||||
}
|
||||
|
||||
MetaCompWindow *
|
||||
meta_comp_screen_lookup_window (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
{
|
||||
return meta_comp_window_lookup (info, xwindow);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
update_frame_counter (void)
|
||||
@ -650,23 +657,6 @@ meta_comp_screen_set_target_rect (MetaCompScreen *info,
|
||||
cm_drawable_node_set_scale_rect (node, rect);
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_set_explode (MetaCompScreen *info,
|
||||
Window xwindow,
|
||||
gdouble level)
|
||||
{
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (find_node (info, xwindow));
|
||||
|
||||
if (node)
|
||||
{
|
||||
#if 0
|
||||
g_print ("level: %f\n", level);
|
||||
#endif
|
||||
|
||||
cm_drawable_node_set_explosion_level (node, level);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_screen_hide_window (MetaCompScreen *info,
|
||||
Window xwindow)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "screen.h"
|
||||
#include "c-window.h"
|
||||
|
||||
typedef struct MetaCompScreen MetaCompScreen;
|
||||
|
||||
@ -48,4 +49,5 @@ void meta_comp_screen_hide_window (MetaCompScreen *info,
|
||||
Window xwindow);
|
||||
void meta_comp_screen_unmap (MetaCompScreen *info,
|
||||
Window xwindow);
|
||||
|
||||
MetaCompWindow *meta_comp_screen_lookup_window (MetaCompScreen *info,
|
||||
Window xwindow);
|
||||
|
308
src/c-window.c
308
src/c-window.c
@ -28,7 +28,9 @@
|
||||
#include <cm/node.h>
|
||||
#include <cm/drawable-node.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "effects.h"
|
||||
#include "c-window.h"
|
||||
#include "window.h"
|
||||
|
||||
@ -42,8 +44,124 @@ struct _MetaCompWindow
|
||||
WsSyncAlarm *alarm;
|
||||
|
||||
WsRectangle size;
|
||||
gboolean waiting_for_paint;
|
||||
};
|
||||
|
||||
static Window
|
||||
find_app_window (MetaCompWindow *comp_window)
|
||||
{
|
||||
Window xwindow = WS_RESOURCE_XID (comp_window->drawable);
|
||||
MetaWindow *meta_window =
|
||||
meta_display_lookup_x_window (comp_window->display, xwindow);
|
||||
|
||||
if (meta_window)
|
||||
return meta_window->xwindow;
|
||||
else
|
||||
return xwindow;
|
||||
}
|
||||
|
||||
static WsPixmap *
|
||||
take_snapshot (WsDrawable *drawable)
|
||||
{
|
||||
WsDisplay *display = WS_RESOURCE (drawable)->display;
|
||||
WsRectangle geometry;
|
||||
WsPixmap *pixmap;
|
||||
|
||||
ws_display_begin_error_trap (display);
|
||||
|
||||
ws_drawable_query_geometry (drawable, &geometry);
|
||||
|
||||
pixmap = ws_pixmap_new (drawable, geometry.width, geometry.height);
|
||||
|
||||
ws_drawable_copy_area (drawable, 0, 0, geometry.width, geometry.height,
|
||||
WS_DRAWABLE (pixmap), 0, 0,
|
||||
NULL);
|
||||
|
||||
ws_display_end_error_trap (display);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
static void
|
||||
on_alarm (WsSyncAlarm *alarm,
|
||||
WsAlarmNotifyEvent *event,
|
||||
MetaCompWindow *window)
|
||||
{
|
||||
if (window->pixmap)
|
||||
g_object_unref (window->pixmap);
|
||||
|
||||
window->pixmap = take_snapshot (window->drawable);
|
||||
|
||||
ws_sync_alarm_set (window->alarm, event->counter_value + 2);
|
||||
ws_sync_counter_change (event->counter, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_counter (MetaCompWindow *comp_window)
|
||||
{
|
||||
Window xwindow = find_app_window (comp_window);
|
||||
WsDisplay *display = WS_RESOURCE (comp_window->drawable)->display;
|
||||
WsWindow *window = ws_window_lookup (display, xwindow);
|
||||
WsSyncCounter *counter;
|
||||
|
||||
ws_display_init_sync (display);
|
||||
|
||||
counter = ws_window_get_property_sync_counter (
|
||||
window, "_NET_WM_FINISH_FRAME_COUNTER");
|
||||
|
||||
if (counter)
|
||||
{
|
||||
WsSyncAlarm *alarm;
|
||||
gint64 value = ws_sync_counter_query_value (counter);
|
||||
|
||||
g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
|
||||
alarm = ws_sync_alarm_new (display, counter);
|
||||
|
||||
g_signal_connect (alarm, "alarm_notify_event",
|
||||
G_CALLBACK (on_alarm), comp_window);
|
||||
|
||||
if (value % 2 == 1)
|
||||
{
|
||||
ws_sync_alarm_set (alarm, value + 2);
|
||||
|
||||
g_print ("wait for %lld\n", value + 2);
|
||||
|
||||
g_print ("increasing counter\n");
|
||||
ws_sync_counter_change (counter, 1);
|
||||
|
||||
g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("wait for %lld\n", value + 1);
|
||||
ws_sync_alarm_set (alarm, value + 1);
|
||||
}
|
||||
|
||||
comp_window->alarm = alarm;
|
||||
|
||||
}
|
||||
|
||||
if (counter)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
#if 0
|
||||
if (counter)
|
||||
{
|
||||
g_print ("found counter %lx on %lx\n",
|
||||
WS_RESOURCE_XID (counter),
|
||||
WS_RESOURCE_XID (window));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("no counter found for %lx\n", WS_RESOURCE_XID (window));
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaCompWindow *
|
||||
meta_comp_window_new (MetaDisplay *display,
|
||||
WsDrawable *drawable)
|
||||
@ -68,6 +186,8 @@ meta_comp_window_free (MetaCompWindow *window)
|
||||
{
|
||||
g_object_unref (window->drawable);
|
||||
g_object_unref (window->node);
|
||||
if (window->alarm)
|
||||
g_object_unref (window->alarm);
|
||||
g_free (window);
|
||||
}
|
||||
|
||||
@ -138,118 +258,6 @@ find_meta_window (MetaCompWindow *comp_window)
|
||||
return window;
|
||||
}
|
||||
|
||||
static Window
|
||||
find_app_window (MetaCompWindow *comp_window)
|
||||
{
|
||||
Window xwindow = WS_RESOURCE_XID (comp_window->drawable);
|
||||
MetaWindow *meta_window =
|
||||
meta_display_lookup_x_window (comp_window->display, xwindow);
|
||||
|
||||
if (meta_window)
|
||||
return meta_window->xwindow;
|
||||
else
|
||||
return xwindow;
|
||||
}
|
||||
|
||||
static WsPixmap *
|
||||
take_snapshot (WsDrawable *drawable)
|
||||
{
|
||||
WsDisplay *display = WS_RESOURCE (drawable)->display;
|
||||
WsRectangle geometry;
|
||||
WsPixmap *pixmap;
|
||||
|
||||
ws_display_begin_error_trap (display);
|
||||
|
||||
ws_drawable_query_geometry (drawable, &geometry);
|
||||
|
||||
pixmap = ws_pixmap_new (drawable, geometry.width, geometry.height);
|
||||
|
||||
ws_drawable_copy_area (drawable, 0, 0, geometry.width, geometry.height,
|
||||
WS_DRAWABLE (pixmap), 0, 0,
|
||||
NULL);
|
||||
|
||||
ws_display_end_error_trap (display);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
static void
|
||||
on_alarm (WsSyncAlarm *alarm,
|
||||
WsAlarmNotifyEvent *event,
|
||||
MetaCompWindow *window)
|
||||
{
|
||||
g_print ("received alarm\n");
|
||||
|
||||
if (window->pixmap)
|
||||
g_object_unref (window->pixmap);
|
||||
|
||||
window->pixmap = take_snapshot (window->drawable);
|
||||
|
||||
ws_sync_alarm_set (window->alarm, event->counter_value + 2);
|
||||
ws_sync_counter_change (event->counter, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_counter (MetaCompWindow *comp_window)
|
||||
{
|
||||
Window xwindow = find_app_window (comp_window);
|
||||
WsDisplay *display = WS_RESOURCE (comp_window->drawable)->display;
|
||||
WsWindow *window = ws_window_lookup (display, xwindow);
|
||||
WsSyncCounter *counter;
|
||||
|
||||
ws_display_init_sync (display);
|
||||
|
||||
counter = ws_window_get_property_sync_counter (
|
||||
window, "_NET_WM_FINISH_FRAME_COUNTER");
|
||||
|
||||
if (counter)
|
||||
{
|
||||
WsSyncAlarm *alarm;
|
||||
gint64 value = ws_sync_counter_query_value (counter);
|
||||
|
||||
g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
|
||||
alarm = ws_sync_alarm_new (display, counter);
|
||||
|
||||
g_signal_connect (alarm, "alarm_notify_event",
|
||||
G_CALLBACK (on_alarm), comp_window);
|
||||
|
||||
if (value % 2 == 1)
|
||||
{
|
||||
ws_sync_alarm_set (alarm, value + 2);
|
||||
|
||||
g_print ("wait for %lld\n", value + 2);
|
||||
|
||||
g_print ("increasing counter\n");
|
||||
ws_sync_counter_change (counter, 1);
|
||||
|
||||
g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("wait for %lld\n", value + 1);
|
||||
ws_sync_alarm_set (alarm, value + 1);
|
||||
}
|
||||
|
||||
comp_window->alarm = alarm;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (counter)
|
||||
{
|
||||
g_print ("found counter %lx on %lx\n",
|
||||
WS_RESOURCE_XID (counter),
|
||||
WS_RESOURCE_XID (window));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("no counter found for %lx\n", WS_RESOURCE_XID (window));
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
|
||||
{
|
||||
@ -260,7 +268,8 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
|
||||
double alpha = 1.0;
|
||||
CmDrawableNode *node = CM_DRAWABLE_NODE (comp_window->node);
|
||||
|
||||
if (ws_window_query_mapped (WS_WINDOW (comp_window->drawable)))
|
||||
if (ws_window_query_mapped (WS_WINDOW (comp_window->drawable)) &&
|
||||
!comp_window->waiting_for_paint)
|
||||
{
|
||||
WsWindow *window = WS_WINDOW (comp_window->drawable);
|
||||
|
||||
@ -268,11 +277,9 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
|
||||
|
||||
find_meta_window (comp_window);
|
||||
|
||||
has_counter (comp_window);
|
||||
|
||||
if (has_type (window, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
|
||||
{
|
||||
alpha = 0.3;
|
||||
alpha = 0.9;
|
||||
}
|
||||
else if (has_type (window, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
|
||||
{
|
||||
@ -284,7 +291,14 @@ meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
|
||||
}
|
||||
|
||||
cm_drawable_node_set_alpha (node, alpha);
|
||||
|
||||
#if 0
|
||||
if (cm_drawable_node_get_viewable (node))
|
||||
g_print ("mapping new window\n");
|
||||
#endif
|
||||
|
||||
cm_drawable_node_set_viewable (node, TRUE);
|
||||
|
||||
cm_drawable_node_update_pixmap (node);
|
||||
}
|
||||
else
|
||||
@ -326,4 +340,66 @@ meta_comp_window_get_node (MetaCompWindow *comp_window)
|
||||
return comp_window->node;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Explosion effect
|
||||
*/
|
||||
#define EXPLODE_TIME 1.0
|
||||
|
||||
#define BASE 0.5
|
||||
|
||||
static double
|
||||
transform (double in)
|
||||
{
|
||||
return (pow (BASE, in) - 1) / (BASE - 1);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaEffect *effect;
|
||||
MetaCompWindow *window;
|
||||
gdouble level;
|
||||
GTimer * timer;
|
||||
} ExplodeInfo;
|
||||
|
||||
static gboolean
|
||||
update_explosion (gpointer data)
|
||||
{
|
||||
ExplodeInfo *info = data;
|
||||
CmDrawableNode *node = (CmDrawableNode *)info->window->node;
|
||||
gdouble elapsed = g_timer_elapsed (info->timer, NULL);
|
||||
|
||||
if (elapsed > EXPLODE_TIME)
|
||||
{
|
||||
meta_effect_end (info->effect);
|
||||
|
||||
cm_drawable_node_set_viewable (node, FALSE);
|
||||
cm_drawable_node_set_explosion_level (node, 0.0);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdouble t = elapsed / EXPLODE_TIME;
|
||||
|
||||
cm_drawable_node_set_explosion_level (node,
|
||||
transform (t));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_comp_window_explode (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect)
|
||||
{
|
||||
ExplodeInfo *info = g_new0 (ExplodeInfo, 1);
|
||||
|
||||
info->window = comp_window;
|
||||
info->effect = effect;
|
||||
info->level = 0.0;
|
||||
info->timer = g_timer_new ();
|
||||
|
||||
g_idle_add (update_explosion, info);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
|
||||
#include <cm/node.h>
|
||||
#include "display.h"
|
||||
#include "effects.h"
|
||||
|
||||
#ifndef C_WINDOW_H
|
||||
#define C_WINDOW_H
|
||||
|
||||
typedef struct _MetaCompWindow MetaCompWindow;
|
||||
|
||||
@ -32,3 +36,14 @@ void meta_comp_window_set_size (MetaCompWindow *window,
|
||||
void meta_comp_window_refresh_attrs (MetaCompWindow *comp_window);
|
||||
void meta_comp_window_set_updates (MetaCompWindow *comp_window,
|
||||
gboolean updates);
|
||||
|
||||
void meta_comp_window_explode (MetaCompWindow *comp_window,
|
||||
MetaEffect *effect);
|
||||
|
||||
#if 0
|
||||
void meta_comp_window_set_explode (MetaCompWindow *comp_window,
|
||||
double level);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
114
src/compositor.c
114
src/compositor.c
@ -50,6 +50,8 @@
|
||||
#include "spring-model.h"
|
||||
#include <cm/state.h>
|
||||
|
||||
#include "effects.h"
|
||||
|
||||
#include "c-screen.h"
|
||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||
|
||||
@ -94,6 +96,39 @@ handle_error (Display *dpy, XErrorEvent *ev, gpointer data)
|
||||
}
|
||||
#endif
|
||||
|
||||
static Window
|
||||
get_xid (MetaWindow *window)
|
||||
{
|
||||
if (window->frame)
|
||||
return window->frame->xwindow;
|
||||
else
|
||||
return window->xwindow;
|
||||
}
|
||||
|
||||
static void
|
||||
do_effect (MetaEffect *effect,
|
||||
gpointer data)
|
||||
{
|
||||
switch (effect->type)
|
||||
{
|
||||
case META_EFFECT_MINIMIZE:
|
||||
{
|
||||
MetaCompScreen *screen = meta_comp_screen_get_by_xwindow (
|
||||
get_xid (effect->u.minimize.window));
|
||||
MetaCompWindow *window =
|
||||
meta_comp_screen_lookup_window (screen, effect->u.minimize.window->frame->xwindow);
|
||||
|
||||
meta_comp_window_explode (window, effect);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MetaCompositor *
|
||||
meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
@ -138,6 +173,8 @@ meta_compositor_new (MetaDisplay *display)
|
||||
|
||||
compositor->enabled = TRUE;
|
||||
|
||||
meta_push_effect_handler (do_effect, compositor);
|
||||
|
||||
return compositor;
|
||||
#else /* HAVE_COMPOSITE_EXTENSIONS */
|
||||
return NULL;
|
||||
@ -673,6 +710,7 @@ interpolate_rectangle (gdouble t,
|
||||
|
||||
#if MINIMIZE_STYLE == 0
|
||||
|
||||
#if 0
|
||||
void
|
||||
meta_compositor_minimize (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
@ -684,6 +722,7 @@ meta_compositor_minimize (MetaCompositor *compositor,
|
||||
gpointer data)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif MINIMIZE_STYLE == 1
|
||||
|
||||
@ -718,15 +757,6 @@ typedef struct
|
||||
gboolean phase_5_started;
|
||||
} MiniInfo;
|
||||
|
||||
static Window
|
||||
get_xid (MetaWindow *window)
|
||||
{
|
||||
if (window->frame)
|
||||
return window->frame->xwindow;
|
||||
else
|
||||
return window->xwindow;
|
||||
}
|
||||
|
||||
static void
|
||||
set_geometry (MiniInfo *info, gdouble elapsed)
|
||||
{
|
||||
@ -923,72 +953,6 @@ run_animation_01 (gpointer data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define EXPLODE_TIME 1.0
|
||||
|
||||
#define BASE 0.5
|
||||
|
||||
static double
|
||||
transform (double in)
|
||||
{
|
||||
return (pow (BASE, in) - 1) / (BASE - 1);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWindow * window;
|
||||
gdouble level;
|
||||
GTimer * timer;
|
||||
MetaAnimationFinishedFunc func;
|
||||
gpointer data;
|
||||
MetaCompScreen * minfo;
|
||||
} ExplodeInfo;
|
||||
|
||||
static gboolean
|
||||
update_explosion (gpointer data)
|
||||
{
|
||||
ExplodeInfo *info = data;
|
||||
gdouble elapsed = g_timer_elapsed (info->timer, NULL);
|
||||
gdouble t = elapsed / EXPLODE_TIME;
|
||||
|
||||
meta_comp_screen_set_explode (info->minfo, get_xid (info->window), transform (t));
|
||||
|
||||
if (elapsed > EXPLODE_TIME)
|
||||
{
|
||||
if (info->func)
|
||||
info->func (info->data);
|
||||
|
||||
meta_comp_screen_hide_window (info->minfo, get_xid (info->window));
|
||||
meta_comp_screen_set_explode (info->minfo, get_xid (info->window), 0.0);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_minimize (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
MetaAnimationFinishedFunc finished,
|
||||
gpointer data)
|
||||
{
|
||||
ExplodeInfo *info = g_new0 (ExplodeInfo, 1);
|
||||
|
||||
info->window = window;
|
||||
info->level = 0.0;
|
||||
info->timer = g_timer_new ();
|
||||
info->func = finished;
|
||||
info->data = data;
|
||||
info->minfo = meta_comp_screen_get_by_xwindow (get_xid (window));
|
||||
|
||||
g_idle_add (update_explosion, info);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
meta_compositor_minimize (MetaCompositor *compositor,
|
||||
|
@ -45,6 +45,7 @@ void meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
void meta_compositor_unmanage_screen (MetaCompositor *compositor,
|
||||
MetaScreen *screen);
|
||||
|
||||
#if 0
|
||||
void meta_compositor_minimize (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
int x,
|
||||
@ -53,6 +54,7 @@ void meta_compositor_minimize (MetaCompositor *compositor,
|
||||
int height,
|
||||
MetaAnimationFinishedFunc finished_cb,
|
||||
gpointer finished_data);
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_compositor_set_updates (MetaCompositor *compositor,
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "effects.h"
|
||||
#include "display.h"
|
||||
#include "ui.h"
|
||||
#include "window.h"
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
@ -72,6 +73,87 @@ typedef struct
|
||||
|
||||
} BoxAnimationContext;
|
||||
|
||||
struct MetaEffectPriv
|
||||
{
|
||||
MetaEffectFinished finished;
|
||||
gpointer finished_data;
|
||||
};
|
||||
|
||||
static void run_default_effect_handler (MetaEffect *effect);
|
||||
|
||||
static MetaEffectHandler effect_handler;
|
||||
static gpointer effect_handler_data;
|
||||
|
||||
void
|
||||
meta_push_effect_handler (MetaEffectHandler handler,
|
||||
gpointer data)
|
||||
{
|
||||
effect_handler = handler;
|
||||
effect_handler_data = data;
|
||||
}
|
||||
|
||||
void
|
||||
meta_pop_effect_handler (void)
|
||||
{
|
||||
/* FIXME: not implemented yet */
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static MetaEffect *
|
||||
create_effect (MetaEffectType type,
|
||||
MetaEffectFinished finished,
|
||||
gpointer finished_data)
|
||||
{
|
||||
MetaEffect *effect = g_new (MetaEffect, 1);
|
||||
|
||||
effect->type = type;
|
||||
effect->priv = g_new (MetaEffectPriv, 1);
|
||||
effect->priv->finished = finished;
|
||||
effect->priv->finished_data = finished_data;
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
void
|
||||
meta_effect_run_minimize (MetaWindow *window,
|
||||
MetaRectangle *window_rect,
|
||||
MetaRectangle *icon_rect,
|
||||
MetaEffectFinished finished,
|
||||
gpointer data)
|
||||
{
|
||||
MetaEffect *effect;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
g_return_if_fail (icon_rect != NULL);
|
||||
|
||||
effect = create_effect (META_EFFECT_MINIMIZE,
|
||||
finished, data);
|
||||
|
||||
effect->u.minimize.window = window;
|
||||
effect->u.minimize.window_rect = *window_rect;
|
||||
effect->u.minimize.icon_rect = *icon_rect;
|
||||
|
||||
if (effect_handler)
|
||||
{
|
||||
effect_handler (effect, effect_handler_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
run_default_effect_handler (effect);
|
||||
meta_effect_end (effect);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_effect_end (MetaEffect *effect)
|
||||
{
|
||||
if (effect->priv->finished)
|
||||
effect->priv->finished (effect, effect->priv->finished_data);
|
||||
|
||||
g_free (effect->priv);
|
||||
g_free (effect);
|
||||
}
|
||||
|
||||
static void
|
||||
update_wireframe_window (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
@ -624,3 +706,20 @@ meta_effects_end_wireframe (MetaScreen *screen,
|
||||
meta_ui_pop_delay_exposes (screen->ui);
|
||||
}
|
||||
|
||||
static void
|
||||
run_default_effect_handler (MetaEffect *effect)
|
||||
{
|
||||
switch (effect->type)
|
||||
{
|
||||
case META_EFFECT_MINIMIZE:
|
||||
meta_effects_draw_box_animation (effect->u.minimize.window->screen,
|
||||
&(effect->u.minimize.window_rect),
|
||||
&(effect->u.minimize.icon_rect),
|
||||
META_MINIMIZE_ANIMATION_LENGTH,
|
||||
META_BOX_ANIM_SCALE);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "util.h"
|
||||
#include "screen.h"
|
||||
|
||||
typedef struct MetaEffect MetaEffect;
|
||||
typedef struct MetaEffectPriv MetaEffectPriv;
|
||||
|
||||
#define META_MINIMIZE_ANIMATION_LENGTH 0.25
|
||||
#define META_SHADE_ANIMATION_LENGTH 0.2
|
||||
|
||||
@ -35,6 +38,51 @@ typedef enum
|
||||
|
||||
} MetaBoxAnimType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_EFFECT_MINIMIZE
|
||||
} MetaEffectType;
|
||||
|
||||
typedef void (* MetaEffectHandler) (MetaEffect *effect,
|
||||
gpointer data);
|
||||
typedef void (* MetaEffectFinished) (const MetaEffect *effect,
|
||||
gpointer data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWindow *window;
|
||||
MetaRectangle window_rect;
|
||||
MetaRectangle icon_rect;
|
||||
} MetaMinimizeEffect;
|
||||
|
||||
struct MetaEffect
|
||||
{
|
||||
MetaEffectType type;
|
||||
gpointer info; /* effect handler can hang data here */
|
||||
|
||||
union
|
||||
{
|
||||
MetaMinimizeEffect minimize;
|
||||
} u;
|
||||
|
||||
MetaEffectPriv *priv;
|
||||
};
|
||||
|
||||
void meta_push_effect_handler (MetaEffectHandler handler,
|
||||
gpointer data);
|
||||
void meta_pop_effect_handler (void);
|
||||
|
||||
void meta_effect_run_minimize (MetaWindow *window,
|
||||
MetaRectangle *window_rect,
|
||||
MetaRectangle *target,
|
||||
MetaEffectFinished finished,
|
||||
gpointer data);
|
||||
void meta_effect_end (MetaEffect *effect);
|
||||
|
||||
|
||||
|
||||
/* Stuff that should become static functions */
|
||||
|
||||
void meta_effects_draw_box_animation (MetaScreen *screen,
|
||||
MetaRectangle *initial_rect,
|
||||
MetaRectangle *destination_rect,
|
||||
|
28
src/window.c
28
src/window.c
@ -1324,7 +1324,8 @@ meta_window_should_be_showing (MetaWindow *window)
|
||||
}
|
||||
|
||||
static void
|
||||
finish_minimize (gpointer data)
|
||||
finish_minimize (const MetaEffect *effect,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWindow *window = data;
|
||||
|
||||
@ -1381,32 +1382,15 @@ implement_showing (MetaWindow *window,
|
||||
|
||||
meta_window_get_outer_rect (window, &window_rect);
|
||||
|
||||
if (window->display->compositor)
|
||||
{
|
||||
/* Draw a nice cool animation */
|
||||
meta_compositor_minimize (window->display->compositor,
|
||||
window,
|
||||
icon_rect.x,
|
||||
icon_rect.y,
|
||||
icon_rect.width,
|
||||
icon_rect.height,
|
||||
meta_effect_run_minimize (window,
|
||||
&window_rect,
|
||||
&icon_rect,
|
||||
finish_minimize,
|
||||
window);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_effects_draw_box_animation (window->screen,
|
||||
&window_rect,
|
||||
&icon_rect,
|
||||
META_MINIMIZE_ANIMATION_LENGTH,
|
||||
META_BOX_ANIM_SCALE);
|
||||
|
||||
finish_minimize (window);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
finish_minimize (window);
|
||||
finish_minimize (NULL, window);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user