summaryrefslogtreecommitdiff
path: root/src/c-window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/c-window.c')
-rw-r--r--src/c-window.c1259
1 files changed, 0 insertions, 1259 deletions
diff --git a/src/c-window.c b/src/c-window.c
deleted file mode 100644
index 43cb7067..00000000
--- a/src/c-window.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2006 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-
-#include <X11/Xlib.h>
-#include <glib.h>
-#include <cm/ws.h>
-#include <cm/wsint.h>
-#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"
-#include "frame.h"
-#include "compositor.h"
-#include "workspace.h"
-
-typedef struct UnminimizeInfo UnminimizeInfo;
-
-struct _MetaCompWindow
-{
- MetaDisplay *display;
- MetaScreen *screen;
- WsDrawable *drawable;
- WsPixmap *pixmap;
- CmDrawableNode *node;
- gboolean updates;
- WsSyncAlarm *alarm;
-
- WsRectangle size;
- gboolean waiting_for_paint;
-
- gint64 counter_value;
- gint ref_count;
-
- gboolean animation_in_progress;
- gboolean hide_after_animation;
-
- int stack_freeze_count;
- int fade_in_idle_id;
-
- MetaCompWindowDestroy destroy;
- gpointer closure;
-
- UnminimizeInfo *unminimize_info;
-};
-
-static void cancel_fade (MetaCompWindow *comp_window);
-static void start_unminimize (MetaCompWindow *comp_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)
-{
- 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);
-
-#if 0
- g_print ("counter value %lld\n", ws_sync_counter_query_value (counter));
- alarm = ws_sync_alarm_new (WS_RESOURCE (comp_window->drawable)->display,
-
- display, counter);
-#endif
-
- g_signal_connect (alarm, "alarm_notify_event",
- G_CALLBACK (on_alarm), comp_window);
-
- if (value % 2 == 1)
- {
- ws_sync_alarm_set (alarm, value + 2);
-
-#if 0
- g_print ("wait for %lld\n", value + 2);
-
- g_print ("increasing counter\n");
-#endif
- ws_sync_counter_change (counter, 1);
-
-#if 0
- g_print ("counter value %lld\n",
- ws_sync_counter_query_value (counter));
-#endif
- }
- else
- {
-#if 0
- g_print ("wait for %lld\n", value + 1);
-#endif
- 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;
-}
-
-void
-meta_comp_window_show (MetaCompWindow *comp_window)
-{
- if (comp_window->animation_in_progress)
- comp_window->hide_after_animation = FALSE;
-
- cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node), TRUE);
- cm_drawable_node_update_pixmap (CM_DRAWABLE_NODE (comp_window->node));
-}
-
-void
-meta_comp_window_hide (MetaCompWindow *comp_window)
-{
- if (comp_window->animation_in_progress)
- {
- comp_window->hide_after_animation = TRUE;
- return;
- }
-
- cancel_fade (comp_window);
-
- cm_drawable_node_set_viewable (CM_DRAWABLE_NODE (comp_window->node),
- FALSE);
-}
-
-MetaCompWindow *
-meta_comp_window_new (MetaScreen *screen,
- WsDrawable *drawable,
- MetaCompWindowDestroy destroy,
- gpointer closure)
-{
- MetaDisplay *display = screen->display;
- MetaCompWindow *window;
- WsRectangle geometry;
-
- ws_drawable_query_geometry (drawable, &geometry);
-
- window = g_new0 (MetaCompWindow, 1);
-
- window->screen = screen;
- window->display = display;
- window->drawable = g_object_ref (drawable);
- window->node = cm_drawable_node_new (drawable, &geometry);
- window->updates = TRUE;
- window->counter_value = 1;
- window->ref_count = 1;
- window->destroy = destroy;
- window->closure = closure;
-
- meta_comp_window_hide (window);
-
- return window;
-}
-
-static MetaCompWindow *
-comp_window_ref (MetaCompWindow *comp_window)
-{
- comp_window->ref_count++;
-
- return comp_window;
-}
-
-static gboolean
-comp_window_unref (MetaCompWindow *comp_window)
-{
- if (--comp_window->ref_count == 0)
- {
- if (comp_window->destroy)
- comp_window->destroy (comp_window, comp_window->closure);
-
- g_object_unref (comp_window->drawable);
- g_object_unref (comp_window->node);
- if (comp_window->alarm)
- g_object_unref (comp_window->alarm);
- memset (comp_window, 'e', sizeof (MetaCompWindow));
- g_free (comp_window);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-gboolean
-meta_comp_window_free (MetaCompWindow *window)
-{
- return comp_window_unref (window);
-}
-
-void
-meta_comp_window_set_size (MetaCompWindow *comp_window,
- WsRectangle *rect)
-{
- if (comp_window->updates)
- {
- WsWindow *window = WS_WINDOW (comp_window->drawable);
- WsDisplay *display = WS_RESOURCE (window)->display;
- CmDrawableNode *dnode = CM_DRAWABLE_NODE (comp_window->node);
- WsRegion *shape;
-
- ws_display_begin_error_trap (display);
-
- cm_drawable_node_set_geometry (dnode, rect);
- shape = ws_window_get_output_shape (window);
- cm_drawable_node_set_shape (dnode, shape);
- ws_region_destroy (shape);
-
- if (rect->width != comp_window->size.width ||
- rect->height != comp_window->size.height)
- {
- cm_drawable_node_update_pixmap (dnode);
- }
-
- comp_window->size = *rect;
-
- ws_display_end_error_trap (display);
- }
-}
-
-static gboolean
-has_type (WsWindow *window, const char *check_type)
-{
- gchar **types = ws_window_get_property_atom_list (window, "_NET_WM_WINDOW_TYPE");
- int i;
- gboolean result;
-
- if (!types)
- return FALSE;
-
- result = FALSE;
-
- for (i = 0; types[i] != NULL; ++i)
- {
- gchar *type = types[i];
-
- if (strcmp (type, check_type) == 0)
- {
- result = TRUE;
- break;
- }
- }
-
- g_strfreev (types);
- return result;
-}
-
-static MetaWindow *
-find_meta_window (MetaCompWindow *comp_window)
-{
- Window xwindow = WS_RESOURCE_XID (comp_window->drawable);
- MetaWindow *window =
- meta_display_lookup_x_window (comp_window->display, xwindow);
-
- return window;
-}
-
-static void
-send_configure_notify (WsDrawable *drawable)
-{
- WsWindow *window = WS_WINDOW (drawable);
- WsRectangle geo;
-
- ws_drawable_query_geometry (drawable, &geo);
-
-#if 0
- g_print ("sending configure notify %d %d %d %d\n",
- geo.x, geo.y, geo.width, geo.height);
-#endif
-
- ws_window_send_configure_notify (
- window, geo.x, geo.y, geo.width, geo.height,
- 0 /* border width */, ws_window_query_override_redirect (window));
-}
-
-static WsWindow *
-find_client_window (MetaCompWindow *comp_window)
-{
- MetaWindow *meta_window = find_meta_window (comp_window);
-
- if (meta_window && meta_window->frame)
- {
- WsDisplay *ws_display = WS_RESOURCE (comp_window->drawable)->display;
-
-#if 0
- g_print ("framed window (client: %lx)\n", WS_RESOURCE_XID (comp_window->drawable));
-#endif
-
-#if 0
- g_print ("framed window (client: %lx\n", meta_window->xwindow);
-#endif
-
-#if 0
- g_print ("framed window: %p\n", comp_window);
-#endif
- return ws_window_lookup (ws_display, meta_window->xwindow);
- }
- else
- {
-#if 0
- if (meta_window)
- g_print ("window not framed, but managed (%p)\n", comp_window);
- else
- g_print ("no meta window %p\n", comp_window);
-#endif
-
- return WS_WINDOW (comp_window->drawable);
- }
-}
-
-static gboolean
-private_metacity_window (MetaCompWindow *comp_window)
-{
- /* Returns TRUE if this is a private metacity window
- * such as a tooltip or a menu
- */
- XID xid = WS_RESOURCE_XID (comp_window->drawable);
-
- return meta_ui_window_is_widget (comp_window->screen->ui, xid);
-}
-
-static gboolean
-frameless_managed (MetaCompWindow *comp_window)
-{
- /* For some reason frameless, managed windows don't respond to
- * sync requests messages. FIXME: at some point need to find out
- * what's going on
- */
- MetaWindow *mw = find_meta_window (comp_window);
-
- return mw && !mw->frame;
-}
-
-static gdouble
-interpolate (gdouble t, gdouble begin, gdouble end, double power)
-{
- return (begin + (end - begin) * pow (t, power));
-}
-
-static void
-interpolate_rectangle (gdouble t,
- WsRectangle * from,
- WsRectangle * to,
- WsRectangle * result)
-{
- if (!result)
- return;
-
- result->x = interpolate (t, from->x, to->x, 1);
- result->y = interpolate (t, from->y, to->y, 1);
- result->width = interpolate (t, from->width, to->width, 1);
- result->height = interpolate (t, from->height, to->height, 1);
-}
-
-static void
-comp_window_set_target_rect (MetaCompWindow *window,
- WsRectangle *rect)
-{
- cm_drawable_node_set_scale_rect (window->node, rect);
-}
-
-static void
-comp_window_get_real_size (MetaCompWindow *window,
- WsRectangle *size)
-{
- if (!size)
- return;
-
- cm_drawable_node_get_clipbox (window->node, size);
-}
-
-#define FADE_TIME 0.225
-
-typedef struct
-{
- MetaEffect *effect;
- MetaCompWindow *window;
- GTimer * timer;
- WsRectangle from;
- WsRectangle to;
- gboolean first_time;
- gdouble start_alpha;
- gdouble end_alpha;
-} FadeInfo;
-
-static gboolean
-update_fade (gpointer data)
-{
- FadeInfo *info = data;
- gdouble elapsed = g_timer_elapsed (info->timer, NULL);
- gdouble t = elapsed / FADE_TIME;
-
- if (elapsed >= FADE_TIME)
- {
- comp_window_set_target_rect (info->window, &info->to);
- cm_drawable_node_set_alpha (info->window->node, info->end_alpha);
- cm_drawable_node_unset_patch (info->window->node);
- comp_window_unref (info->window);
- return FALSE;
- }
- else
- {
- gdouble alpha = interpolate (t, info->start_alpha, info->end_alpha, 1.0);
- WsRectangle cur;
-
- if (info->first_time)
- {
- meta_comp_window_show (info->window);
- info->first_time = FALSE;
- }
-
- interpolate_rectangle (t, &info->from, &info->to, &cur);
- comp_window_set_target_rect (info->window, &cur);
- cm_drawable_node_set_alpha (info->window->node, alpha);
- return TRUE;
- }
-}
-
-static void
-cancel_fade (MetaCompWindow *comp_window)
-{
- if (comp_window->fade_in_idle_id)
- {
- g_source_remove (comp_window->fade_in_idle_id);
- comp_window->fade_in_idle_id = 0;
- }
-}
-
-static void
-meta_comp_window_fade_in (MetaCompWindow *comp_window)
-{
- FadeInfo *info = g_new0 (FadeInfo, 1);
- WsWindow *window = find_client_window (comp_window);
-
- if (comp_window->fade_in_idle_id)
- return;
-
- info->window = comp_window_ref (comp_window);
- info->timer = g_timer_new ();
-
- comp_window_get_real_size (info->window, &info->to);
- info->from = info->to;
-
- info->start_alpha = 0.1;
- info->first_time = TRUE;
-
- if (has_type (window, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU") ||
- has_type (window, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
- {
- info->end_alpha = 0.9;
- info->from.width *= 0.6;
- info->from.height *= 0.4;
- }
- else if (has_type (window, "_NET_WM_WINDOW_TYPE_DIALOG"))
- {
- info->end_alpha = 0.9;
- }
- else
- {
- info->end_alpha = 1.0;
- }
-
- comp_window->fade_in_idle_id = g_idle_add (update_fade, info);
-}
-
-static void
-on_request_alarm (WsSyncAlarm *alarm,
- WsAlarmNotifyEvent *event,
- MetaCompWindow *comp_window)
-{
- /* This alarm means that the window is ready to be shown on screen */
-
- if (comp_window->unminimize_info)
- start_unminimize (comp_window);
- else
- meta_comp_window_fade_in (comp_window);
-
- g_object_unref (alarm);
-}
-
-static gboolean
-send_sync_request (MetaCompWindow *comp_window)
-{
- WsDisplay *display;
- WsWindow *client_window = find_client_window (comp_window);
- WsSyncCounter *request_counter;
- WsSyncAlarm *alarm;
- guint32 msg[5];
- display = WS_RESOURCE (comp_window->drawable)->display;
- ws_display_init_sync (display);
-
- if (!client_window)
- return FALSE;
-
- request_counter = ws_window_get_property_sync_counter (
- client_window, "_NET_WM_SYNC_REQUEST_COUNTER");
-
- if (!request_counter)
- return FALSE;
-
- comp_window->counter_value = ws_sync_counter_query_value (request_counter) + 1;
-
- msg[0] = comp_window->display->atom_net_wm_sync_request;
- msg[1] = meta_display_get_current_time (comp_window->display);
- msg[2] = comp_window->counter_value & 0xffffffff;
- msg[3] = (comp_window->counter_value >> 32) & 0xffffffff;
-
- alarm = ws_sync_alarm_new (display, request_counter);
-
- ws_sync_alarm_set (alarm, comp_window->counter_value);
-
- g_signal_connect (alarm, "alarm_notify_event",
- G_CALLBACK (on_request_alarm), comp_window);
-
- ws_window_send_client_message (client_window,
- "WM_PROTOCOLS", msg);
-
- send_configure_notify (WS_DRAWABLE (client_window));
-
- ws_display_flush (WS_RESOURCE (client_window)->display);
-
- return TRUE;
-}
-
-void
-meta_comp_window_refresh_attrs (MetaCompWindow *comp_window)
-{
- /* FIXME: this function should not exist - the real problem is
- * probably in meta_screen_info_add_window() where it it called.
- */
-
- double alpha = 1.0;
- CmDrawableNode *node = CM_DRAWABLE_NODE (comp_window->node);
-
-#if 0
- g_print ("waiting for paint: %d\n", comp_window->waiting_for_paint);
-#endif
-
- if (ws_window_query_mapped (WS_WINDOW (comp_window->drawable))
-#if 0
- && !comp_window->waiting_for_paint
-#endif
- )
- {
- WsWindow *window = WS_WINDOW (comp_window->drawable);
-
- cm_drawable_node_unset_patch (CM_DRAWABLE_NODE (node));
-
- if (has_type (window, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
- {
- alpha = 0.9;
- }
- else if (has_type (window, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
- {
- alpha = 0.9;
- }
- else
- {
- alpha = 1.0;
- }
-
- cm_drawable_node_set_alpha (node, alpha);
-
- if (!cm_drawable_node_get_viewable (node))
- {
- comp_window->waiting_for_paint = TRUE;
-#if 0
- alarm = ws_alarm_new (comp_window->display);
-#endif
-#if 0
- finish_counter = ws_window_get_property_sync_counter (
- window, "_NET_WM_FINISH_FRAME_COUNTER");
-#endif
-
- /* For some reason the panel and nautilus don't respond to the
- * sync counter stuff. FIXME: this should be figured out at
- * some point.
- */
- if (frameless_managed (comp_window) ||
- private_metacity_window (comp_window) ||
- !send_sync_request (comp_window))
- {
- meta_comp_window_show (comp_window);
- }
- }
- }
- else
- {
-#if 0
- g_print ("unmapping %p\n", node);
-#endif
-
- meta_comp_window_hide (comp_window);
- }
-}
-
-void
-meta_comp_window_set_updates (MetaCompWindow *comp_window,
- gboolean updates)
-{
- CmDrawableNode *node = CM_DRAWABLE_NODE (comp_window->node);
-
- comp_window->updates = updates;
-
- cm_drawable_node_set_updates (node, updates);
-
- if (updates)
- {
- WsRectangle rect;
- WsRegion *shape;
- WsDisplay *display = WS_RESOURCE (node->drawable)->display;
-
- ws_display_begin_error_trap (display);
- ws_drawable_query_geometry (node->drawable, &rect);
- cm_drawable_node_update_pixmap (node);
- cm_drawable_node_set_geometry (node, &rect);
- shape = ws_window_get_output_shape (WS_WINDOW (node->drawable));
- cm_drawable_node_set_shape (node, shape);
- ws_region_destroy (shape);
- ws_display_end_error_trap (display);
- }
-}
-
-CmNode *
-meta_comp_window_get_node (MetaCompWindow *comp_window)
-{
- return CM_NODE (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 *comp_window;
- gdouble level;
- GTimer * timer;
-} ExplodeInfo;
-
-static gboolean
-update_explosion (gpointer data)
-{
- ExplodeInfo *info = data;
- CmDrawableNode *node = CM_DRAWABLE_NODE (info->comp_window->node);
- gdouble elapsed = g_timer_elapsed (info->timer, NULL);
-
- if (!cm_drawable_node_get_viewable (node) || elapsed > EXPLODE_TIME)
- {
- meta_effect_end (info->effect);
-
- info->comp_window->animation_in_progress = FALSE;
- if (info->comp_window->hide_after_animation)
- meta_comp_window_hide (info->comp_window);
-
- cm_drawable_node_set_explosion_level (node, 0.0);
-
- comp_window_unref (info->comp_window);
- 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);
-
- if (!cm_drawable_node_get_viewable (comp_window->node))
- return;
-
- comp_window->animation_in_progress = TRUE;
-
- info->comp_window = comp_window_ref (comp_window);
- info->effect = effect;
- info->level = 0.0;
- info->timer = g_timer_new ();
-
- g_idle_add (update_explosion, info);
-}
-
-/* shrinkydink minimize effect */
-
-#define N_PHASES 5
-
-typedef struct
-{
- WsRectangle start_rect;
- WsRectangle end_rect;
- gdouble start_alpha;
- gdouble end_alpha;
- gdouble start_time;
- gdouble end_time;
-} Phase;
-
-typedef struct
-{
- GTimer *timer;
-
- MetaCompWindow *comp_window;
-
- MetaEffect *effect;
-
- Phase phases[N_PHASES];
-} MiniInfo;
-
-static void
-set_geometry (MetaCompWindow *window,
- Phase *phase,
- gdouble elapsed)
-{
- WsRectangle rect;
- gdouble alpha;
- gdouble t = (elapsed - phase->start_time) / (phase->end_time - phase->start_time);
-
- interpolate_rectangle (t, &phase->start_rect, &phase->end_rect, &rect);
- alpha = interpolate (t, phase->start_alpha, phase->end_alpha, 1.0);
-
- comp_window_set_target_rect (window, &rect);
- cm_drawable_node_set_alpha (window->node, alpha);
-}
-
-static int
-center (gdouble what, gdouble in)
-{
- return (in - what) / 2.0 + 0.5;
-}
-
-#define WOBBLE_FACTOR 1.5
-
-static void
-generate_phases (WsRectangle *start,
- WsRectangle *icon,
- Phase phases[N_PHASES])
-{
- const double phase_times[5] = {
- 0.225, /* scale to size of button */
- 0.100, /* scale up a little */
- 0.100, /* scale back a little */
- 0.100, /* drop down to icon */
- 0.350, /* fade out */
- };
-
- WsRectangle cur;
- gdouble alpha;
- gdouble aspect_ratio;
- gdouble time;
- int i;
-
- aspect_ratio = (double)start->width / (double)start->height;
- cur = *start;
- time = 0.0;
- alpha = 1.0;
- for (i = 0; i < N_PHASES; ++i)
- {
- Phase *phase = &(phases[i]);
- WsRectangle *end = &(phase->end_rect);
-
- phase->start_time = time;
- phase->start_rect = cur;
- phase->start_alpha = alpha;
- phase->end_alpha = 1.0;
- phase->end_time = time + phase_times[i];
-
- if (i == 0)
- {
- /* Shrink to a little rectangle */
- end->height = icon->height;
- end->width = icon->height * aspect_ratio;
-#if 0
- end->x = icon->x + center (end->width, icon->width);
-#endif
- end->x = cur.x + center (end->width, cur.width);
- end->y = cur.y + center (icon->height, cur.height);
- }
- else if (i == 1)
- {
- /* Zoom out a little */
- end->x = cur.x + center (WOBBLE_FACTOR * cur.width, cur.width);
- end->y = cur.y + center (WOBBLE_FACTOR * cur.height, cur.height);
- end->width = cur.width * WOBBLE_FACTOR;
- end->height = cur.height * WOBBLE_FACTOR;
- }
- else if (i == 2)
- {
- /* Zoom back */
- end->height = icon->height;
- end->width = icon->height * aspect_ratio;
-#if 0
- end->x = icon->x + center (end->width, icon->width);
-#endif
- end->x = cur.x + center (end->width, cur.width);
- end->y = cur.y + center (icon->height, cur.height);
- }
- else if (i == 3)
- {
- /* Move down to the button */
- end->height = icon->height;
- end->width = icon->height * aspect_ratio;
- end->x = icon->x + center (end->width, icon->width);
- end->y = icon->y;
- }
- else if (i == 4)
- {
- /* Fade out */
- end->x = icon->x;
- end->y = icon->y;
- end->width = icon->width;
- end->height = icon->height;
-
- phases[i].end_alpha = 0.0;
- }
-
- alpha = phase->end_alpha;
- cur = phase->end_rect;
- time += phase_times[i];
- }
-}
-
-static gboolean
-update_minimize (gpointer data)
-{
- MiniInfo *info = data;
- Phase *current_phase;
- int i;
- gdouble elapsed = g_timer_elapsed (info->timer, NULL);
-
- current_phase = NULL;
- for (i = 0; i < N_PHASES; ++i)
- {
- Phase *p = &(info->phases[i]);
-
- if (p->start_time < elapsed && p->end_time >= elapsed)
- {
- current_phase = p;
- break;
- }
- }
-
- if (current_phase)
- {
- set_geometry (info->comp_window, current_phase, elapsed);
- return TRUE;
- }
- else
- {
- meta_comp_window_hide (info->comp_window);
- cm_drawable_node_set_alpha (info->comp_window->node, 1.0);
- cm_drawable_node_unset_patch (info->comp_window->node);
- comp_window_unref (info->comp_window);
-
- meta_effect_end (info->effect);
-
- return FALSE;
- }
-}
-
-static void
-meta_rect_to_ws_rect (MetaRectangle *mrect,
- WsRectangle *wrect)
-{
- if (!mrect || !wrect)
- return;
-
- wrect->x = mrect->x;
- wrect->y = mrect->y;
- wrect->width = mrect->width;
- wrect->height = mrect->height;
-}
-
-void
-meta_comp_window_run_minimize (MetaCompWindow *window,
- MetaEffect *effect)
-{
- MiniInfo *info = g_new (MiniInfo, 1);
- WsRectangle start, end;
-
- info->timer = g_timer_new ();
-
- info->comp_window = comp_window_ref (window);
-
- info->effect = effect;
-
- meta_rect_to_ws_rect (&(effect->u.minimize.window_rect), &start);
- meta_rect_to_ws_rect (&(effect->u.minimize.icon_rect), &end);
-
- generate_phases (&start, &end, info->phases);
-
- g_idle_add (update_minimize, info);
-}
-
-struct UnminimizeInfo
-{
- GTimer *timer;
-
- MetaCompWindow *comp_window;
-
- Phase phases[N_PHASES];
- gboolean first_time;
-};
-
-#define WOBBLE_FACTOR_OUT 0.7
-
-static void
-generate_unminimize_phases (WsRectangle *icon,
- WsRectangle *full,
- Phase phases[N_PHASES])
-{
- const double phase_times[5] = {
- 0.350, /* fade in */
- 0.100, /* move up from icon */
- 0.225, /* scale to full size */
- 0.100, /* scale down a little */
- 0.100, /* scale to full size */
- };
-
- WsRectangle cur;
- gdouble aspect_ratio;
- gdouble time;
- int i;
-
- aspect_ratio = (double)full->width / (double)full->height;
- cur = *icon;
- time = 0.0;
- for (i = 0; i < N_PHASES; ++i)
- {
- Phase *phase = &(phases[i]);
- WsRectangle *end = &(phase->end_rect);
-
- phase->start_time = time;
- phase->start_rect = cur;
- phase->start_alpha = 1.0;
- phase->end_alpha = 1.0;
- phase->end_time = time + phase_times[i];
-
- if (i == 0)
- {
- /* Fade in */
- phase->end_alpha = 1.0;
- phase->start_alpha = 0.0;
- end->height = icon->height;
- end->width = icon->height * aspect_ratio;
- end->x = icon->x + center (end->width, icon->width);
- end->y = icon->y;
- }
- else if (i == 1)
- {
- /* Move up from icon */
- end->width = cur.width;
- end->height = cur.height;
-#if 0
- end->x = cur.x;
-#endif
- end->x = full->x + center (end->width, full->width);
- end->y = full->y + center (icon->height, full->height);
- }
- else if (i == 2)
- {
- /* Zoom to full size */
- *end = *full;
- }
- else if (i == 3)
- {
- /* Scale down a little */
- end->x = cur.x + center (cur.width * WOBBLE_FACTOR_OUT, cur.width);
- end->y = cur.y + center (cur.height * WOBBLE_FACTOR_OUT, cur.height);
- end->width = cur.width * WOBBLE_FACTOR_OUT;
- end->height = cur.height * WOBBLE_FACTOR_OUT;
- }
- else if (i == 4)
- {
- /* Scale up to full size again */
- *end = *full;
- }
-
- cur = phase->end_rect;
- time += phase_times[i];
- }
-}
-
-static gboolean
-update_unminimize (gpointer data)
-{
- UnminimizeInfo *info = data;
- Phase *current_phase;
- int i;
- gdouble elapsed = g_timer_elapsed (info->timer, NULL);
-
- current_phase = NULL;
- for (i = 0; i < N_PHASES; ++i)
- {
- Phase *p = &(info->phases[i]);
-
- if (p->start_time < elapsed && p->end_time >= elapsed)
- {
- current_phase = p;
- break;
- }
- }
-
- if (current_phase)
- {
- if (info->first_time)
- {
- meta_comp_window_show (info->comp_window);
- info->first_time = FALSE;
- }
-
- set_geometry (info->comp_window, current_phase, elapsed);
- return TRUE;
- }
- else
- {
- cm_drawable_node_set_alpha (info->comp_window->node, 1.0);
- cm_drawable_node_unset_patch (info->comp_window->node);
- comp_window_unref (info->comp_window);
-#if 0
- g_print ("done\n");
-#endif
-
- return FALSE;
- }
-
-}
-
-static void
-start_unminimize (MetaCompWindow *comp_window)
-{
- UnminimizeInfo *info = comp_window->unminimize_info;
-
- if (!info)
- return;
-
- comp_window->unminimize_info = NULL;
-
- info->timer = g_timer_new ();
- info->first_time = TRUE;
-
- g_idle_add (update_unminimize, info);
-}
-
-void
-meta_comp_window_run_unminimize (MetaCompWindow *comp_window,
- MetaEffect *effect)
-{
- WsRectangle start, end;
- UnminimizeInfo *info = g_new0 (UnminimizeInfo, 1);
-
- meta_rect_to_ws_rect (&(effect->u.unminimize.icon_rect), &start);
- meta_rect_to_ws_rect (&(effect->u.unminimize.window_rect), &end);
-
- generate_unminimize_phases (&start, &end, info->phases);
-
- info->comp_window = comp_window_ref (comp_window);
-
- comp_window->unminimize_info = info;
-
- meta_effect_end (effect);
-}
-
-/* bounce effect */
-
-typedef struct
-{
- MetaEffect *effect;
- MetaCompWindow *window;
- GTimer *timer;
- Model *model;
- MetaRectangle rect;
- gdouble last_time;
-} FocusInfo;
-
-static gboolean
-update_focus (gpointer data)
-{
- FocusInfo *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_run_focus (MetaCompWindow *comp_window,
- MetaEffect *effect)
-{
- FocusInfo *info = g_new0 (FocusInfo, 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_focus, info);
-}
-
-void
-meta_comp_window_freeze_stack (MetaCompWindow *comp_window)
-{
- comp_window->stack_freeze_count++;
-}
-
-void
-meta_comp_window_thaw_stack (MetaCompWindow *comp_window)
-{
- comp_window->stack_freeze_count--;
-}
-
-gboolean
-meta_comp_window_stack_frozen (MetaCompWindow *comp_window)
-{
- return comp_window->stack_freeze_count > 0;
-}
-
-#endif
-