summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--src/Makefile.am2
-rw-r--r--src/display.c4
-rw-r--r--src/display.h1
-rw-r--r--src/effects.c124
-rw-r--r--src/effects.h37
-rw-r--r--src/window.c93
7 files changed, 266 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index ccd06c5d..f8f01e38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2001-08-05 Anders Carlsson <andersca@gnu.org>
+
+ * src/display.h, src/display.c: Add _NET_WM_ICON_GEOMETRY atom.
+
+ * src/window.c (meta_window_calc_showing): See if the window has
+ an icon geometry and show a morphing animation from the window's
+ coordinates to the icon's coordinates.
+ (meta_window_get_icon_geometry): New function that fetches a
+ window's icon geometry.
+
+ * src/Makefile.am: Add effects.[ch].
+
+ * src/effects.c: New file with cool effects.
+
2001-08-03 Havoc Pennington <hp@pobox.com>
* src/keybindings.c: Add Alt + left/right arrow to
diff --git a/src/Makefile.am b/src/Makefile.am
index dbd3e163..bec595fa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,8 @@ metacity_SOURCES= \
core.h \
display.c \
display.h \
+ effects.c \
+ effects.h \
errors.c \
errors.h \
eventqueue.c \
diff --git a/src/display.c b/src/display.c
index ccc82e85..66916215 100644
--- a/src/display.c
+++ b/src/display.c
@@ -130,7 +130,8 @@ meta_display_open (const char *name)
"_WIN_PROTOCOLS",
"_WIN_SUPPORTING_WM_CHECK",
"_NET_WM_ICON_NAME",
- "_NET_WM_ICON"
+ "_NET_WM_ICON",
+ "_NET_WM_ICON_GEOMETRY"
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -212,6 +213,7 @@ meta_display_open (const char *name)
display->atom_win_supporting_wm_check = atoms[35];
display->atom_net_wm_icon_name = atoms[36];
display->atom_net_wm_icon = atoms[37];
+ display->atom_net_wm_icon_geometry = atoms[38];
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new
diff --git a/src/display.h b/src/display.h
index c04d9654..df8dd291 100644
--- a/src/display.h
+++ b/src/display.h
@@ -95,6 +95,7 @@ struct _MetaDisplay
Atom atom_win_supporting_wm_check;
Atom atom_net_wm_icon_name;
Atom atom_net_wm_icon;
+ Atom atom_net_wm_icon_geometry;
/* This is the actual window from focus events,
* not the one we last set
diff --git a/src/effects.c b/src/effects.c
new file mode 100644
index 00000000..b5d7150b
--- /dev/null
+++ b/src/effects.c
@@ -0,0 +1,124 @@
+/* Metacity animation effects */
+
+/*
+ * Copyright (C) 2001 Anders Carlsson, Havoc Pennington
+ *
+ * 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 "effects.h"
+#include "display.h"
+
+typedef struct
+{
+ MetaScreen *screen;
+
+ GC gc;
+
+ int step;
+ int steps;
+
+ double current_x, current_y;
+ double current_width, current_height;
+
+ double delta_x, delta_y;
+ double delta_width, delta_height;
+} BoxAnimationContext;
+
+static gboolean
+effects_draw_box_animation_timeout (BoxAnimationContext *context)
+{
+ if (context->step == 0)
+ {
+ /* It's our first time, grab the X server */
+ meta_display_grab (context->screen->display);
+ }
+ else
+ {
+ /* Restore the previously drawn background */
+ XDrawRectangle (context->screen->display->xdisplay,
+ context->screen->xroot,
+ context->gc,
+ context->current_x, context->current_y,
+ context->current_width, context->current_height);
+ }
+
+ /* Return if we're done */
+ if (context->step == context->steps)
+ {
+ meta_display_ungrab (context->screen->display);
+ XFreeGC (context->screen->display->xdisplay,
+ context->gc);
+ g_free (context);
+ return FALSE;
+ }
+
+ context->current_x += context->delta_x;
+ context->current_y += context->delta_y;
+ context->current_width += context->delta_width;
+ context->current_height += context->delta_height;
+
+ /* Draw the rectangle */
+ XDrawRectangle (context->screen->display->xdisplay,
+ context->screen->xroot,
+ context->gc,
+ context->current_x, context->current_y,
+ context->current_width, context->current_height);
+
+ context->step += 1;
+
+ return TRUE;
+}
+
+void
+meta_effects_draw_box_animation (MetaScreen *screen,
+ MetaRectangle *initial_rect,
+ MetaRectangle *destination_rect,
+ int steps,
+ int delay)
+{
+ BoxAnimationContext *context;
+ XGCValues gc_values;
+
+ /* Create the animation context */
+ context = g_new (BoxAnimationContext, 1);
+
+ gc_values.subwindow_mode = IncludeInferiors;
+ gc_values.function = GXinvert;
+
+ /* Create a gc for the root window */
+ context->screen = screen;
+ context->gc = XCreateGC (screen->display->xdisplay,
+ screen->xroot,
+ GCSubwindowMode | GCFunction,
+ &gc_values);
+ context->step = 0;
+ context->steps = steps;
+ context->delta_x = (destination_rect->x - initial_rect->x) / (double)steps;
+ context->delta_y = (destination_rect->y - initial_rect->y) / (double)steps;
+ context->delta_width = (destination_rect->width - initial_rect->width) / (double)steps;
+ context->delta_height = (destination_rect->height - initial_rect->height) / (double)steps;
+
+ context->current_x = initial_rect->x;
+ context->current_y = initial_rect->y;
+ context->current_width = initial_rect->width;
+ context->current_height = initial_rect->height;
+
+ /* Add the timeout */
+ g_timeout_add (delay,
+ (GSourceFunc)effects_draw_box_animation_timeout,
+ context);
+}
diff --git a/src/effects.h b/src/effects.h
new file mode 100644
index 00000000..d564103e
--- /dev/null
+++ b/src/effects.h
@@ -0,0 +1,37 @@
+/* Metacity animation effects */
+
+/*
+ * Copyright (C) 2001 Anders Carlsson, Havoc Pennington
+ *
+ * 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.
+ */
+
+#ifndef META_EFFECTS_H
+#define META_EFFECTS_H
+
+#include "util.h"
+#include "screen.h"
+
+#define META_MINIMIZE_ANIMATION_STEPS 16
+#define META_MINIMIZE_ANIMATION_DELAY 20
+
+void meta_effects_draw_box_animation (MetaScreen *screen,
+ MetaRectangle *initial_rect,
+ MetaRectangle *destination_rect,
+ int steps,
+ int delay);
+
+#endif /* META_EFFECTS_H */
diff --git a/src/window.c b/src/window.c
index e13bbd40..917ddee0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1,7 +1,7 @@
/* Metacity X managed windows */
/*
- * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2001 Havoc Pennington, Anders Carlsson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -29,6 +29,7 @@
#include "ui.h"
#include "place.h"
#include "session.h"
+#include "effects.h"
#include <X11/Xatom.h>
@@ -70,6 +71,9 @@ static gboolean process_property_notify (MetaWindow *window,
static void meta_window_show (MetaWindow *window);
static void meta_window_hide (MetaWindow *window);
+static gboolean meta_window_get_icon_geometry (MetaWindow *window,
+ MetaRectangle *rect);
+
static void adjust_for_gravity (MetaWindow *window,
MetaFrameGeometry *fgeom,
gboolean coords_assume_border,
@@ -758,6 +762,41 @@ meta_window_calc_showing (MetaWindow *window)
if (window->minimized || !on_workspace)
{
+ /* 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.
+ */
+ if (on_workspace && window->minimized && window->mapped)
+ {
+ 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...
+ */
+ icon_rect.x = window->screen->width;
+ icon_rect.y = window->screen->height;
+ icon_rect.width = 1;
+ icon_rect.height = 1;
+ }
+
+ meta_window_get_outer_rect (window, &window_rect);
+
+ /* Draw a nice cool animation */
+ meta_effects_draw_box_animation (window->screen,
+ &window_rect,
+ &icon_rect,
+ META_MINIMIZE_ANIMATION_STEPS,
+ META_MINIMIZE_ANIMATION_DELAY);
+ }
+
meta_window_hide (window);
}
else
@@ -2668,7 +2707,7 @@ update_net_wm_state (MetaWindow *window)
* clients don't change the property.
*/
Atom type;
- gint format;
+ int format;
gulong n_atoms;
gulong bytes_after;
Atom *atoms;
@@ -2767,7 +2806,7 @@ update_mwm_hints (MetaWindow *window)
{
MotifWmHints *hints;
Atom type;
- gint format;
+ int format;
gulong nitems;
gulong bytes_after;
int result;
@@ -2884,6 +2923,44 @@ update_mwm_hints (MetaWindow *window)
return Success;
}
+static gboolean
+meta_window_get_icon_geometry (MetaWindow *window,
+ MetaRectangle *rect)
+{
+ Atom type;
+ int format;
+ gulong nitems;
+ gulong bytes_after;
+ gulong *geometry;
+ int result;
+
+ meta_error_trap_push (window->display);
+ type = None;
+ XGetWindowProperty (window->display->xdisplay,
+ window->xwindow,
+ window->display->atom_net_wm_icon_geometry,
+ 0, G_MAXLONG,
+ False, XA_CARDINAL, &type, &format, &nitems,
+ &bytes_after, ((guchar **)&geometry));
+
+ result = meta_error_trap_pop (window->display);
+
+ if (result != Success || type != XA_CARDINAL || nitems != 4)
+ return FALSE;
+
+ if (rect)
+ {
+ rect->x = geometry[0];
+ rect->y = geometry[1];
+ rect->width = geometry[2];
+ rect->height = geometry[3];
+ }
+
+ XFree (geometry);
+
+ return TRUE;
+}
+
static int
update_wm_class (MetaWindow *window)
{
@@ -2933,7 +3010,7 @@ read_string_prop (MetaDisplay *display,
char **strp)
{
Atom type;
- gint format;
+ int format;
gulong nitems;
gulong bytes_after;
guchar *str;
@@ -2966,7 +3043,7 @@ read_client_leader (MetaDisplay *display,
Window xwindow)
{
Atom type;
- gint format;
+ int format;
gulong nitems;
gulong bytes_after;
Window *leader;
@@ -3094,7 +3171,7 @@ get_cardinal (MetaDisplay *display,
gulong *val)
{
Atom type;
- gint format;
+ int format;
gulong nitems;
gulong bytes_after;
gulong *num;
@@ -3137,7 +3214,7 @@ static int
update_net_wm_type (MetaWindow *window)
{
Atom type;
- gint format;
+ int format;
gulong n_atoms;
gulong bytes_after;
Atom *atoms;
@@ -3482,7 +3559,7 @@ constrain_size (MetaWindow *window,
/* frame member variables should NEVER be used in here */
-#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
+#define FLOOR(value, base) ( ((int) ((value) / (base))) * (base) )
/* Get the allowed size ranges, considering maximized, etc. */
fullw = window->screen->active_workspace->workarea.width;