Add _NET_WM_ICON_GEOMETRY atom.

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.
This commit is contained in:
Anders Carlsson 2001-08-05 16:04:52 +00:00 committed by rhp
parent 0ee26a5168
commit 971419c880
7 changed files with 266 additions and 9 deletions

View File

@ -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> 2001-08-03 Havoc Pennington <hp@pobox.com>
* src/keybindings.c: Add Alt + left/right arrow to * src/keybindings.c: Add Alt + left/right arrow to

View File

@ -9,6 +9,8 @@ metacity_SOURCES= \
core.h \ core.h \
display.c \ display.c \
display.h \ display.h \
effects.c \
effects.h \
errors.c \ errors.c \
errors.h \ errors.h \
eventqueue.c \ eventqueue.c \

View File

@ -130,7 +130,8 @@ meta_display_open (const char *name)
"_WIN_PROTOCOLS", "_WIN_PROTOCOLS",
"_WIN_SUPPORTING_WM_CHECK", "_WIN_SUPPORTING_WM_CHECK",
"_NET_WM_ICON_NAME", "_NET_WM_ICON_NAME",
"_NET_WM_ICON" "_NET_WM_ICON",
"_NET_WM_ICON_GEOMETRY"
}; };
Atom atoms[G_N_ELEMENTS(atom_names)]; 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_win_supporting_wm_check = atoms[35];
display->atom_net_wm_icon_name = atoms[36]; display->atom_net_wm_icon_name = atoms[36];
display->atom_net_wm_icon = atoms[37]; display->atom_net_wm_icon = atoms[37];
display->atom_net_wm_icon_geometry = atoms[38];
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new * created in screen_new

View File

@ -95,6 +95,7 @@ struct _MetaDisplay
Atom atom_win_supporting_wm_check; Atom atom_win_supporting_wm_check;
Atom atom_net_wm_icon_name; Atom atom_net_wm_icon_name;
Atom atom_net_wm_icon; Atom atom_net_wm_icon;
Atom atom_net_wm_icon_geometry;
/* This is the actual window from focus events, /* This is the actual window from focus events,
* not the one we last set * not the one we last set

124
src/effects.c Normal file
View File

@ -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);
}

37
src/effects.h Normal file
View File

@ -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 */

View File

@ -1,7 +1,7 @@
/* Metacity X managed windows */ /* 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@ -29,6 +29,7 @@
#include "ui.h" #include "ui.h"
#include "place.h" #include "place.h"
#include "session.h" #include "session.h"
#include "effects.h"
#include <X11/Xatom.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_show (MetaWindow *window);
static void meta_window_hide (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, static void adjust_for_gravity (MetaWindow *window,
MetaFrameGeometry *fgeom, MetaFrameGeometry *fgeom,
gboolean coords_assume_border, gboolean coords_assume_border,
@ -758,6 +762,41 @@ meta_window_calc_showing (MetaWindow *window)
if (window->minimized || !on_workspace) 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); meta_window_hide (window);
} }
else else
@ -2668,7 +2707,7 @@ update_net_wm_state (MetaWindow *window)
* clients don't change the property. * clients don't change the property.
*/ */
Atom type; Atom type;
gint format; int format;
gulong n_atoms; gulong n_atoms;
gulong bytes_after; gulong bytes_after;
Atom *atoms; Atom *atoms;
@ -2767,7 +2806,7 @@ update_mwm_hints (MetaWindow *window)
{ {
MotifWmHints *hints; MotifWmHints *hints;
Atom type; Atom type;
gint format; int format;
gulong nitems; gulong nitems;
gulong bytes_after; gulong bytes_after;
int result; int result;
@ -2884,6 +2923,44 @@ update_mwm_hints (MetaWindow *window)
return Success; 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 static int
update_wm_class (MetaWindow *window) update_wm_class (MetaWindow *window)
{ {
@ -2933,7 +3010,7 @@ read_string_prop (MetaDisplay *display,
char **strp) char **strp)
{ {
Atom type; Atom type;
gint format; int format;
gulong nitems; gulong nitems;
gulong bytes_after; gulong bytes_after;
guchar *str; guchar *str;
@ -2966,7 +3043,7 @@ read_client_leader (MetaDisplay *display,
Window xwindow) Window xwindow)
{ {
Atom type; Atom type;
gint format; int format;
gulong nitems; gulong nitems;
gulong bytes_after; gulong bytes_after;
Window *leader; Window *leader;
@ -3094,7 +3171,7 @@ get_cardinal (MetaDisplay *display,
gulong *val) gulong *val)
{ {
Atom type; Atom type;
gint format; int format;
gulong nitems; gulong nitems;
gulong bytes_after; gulong bytes_after;
gulong *num; gulong *num;
@ -3137,7 +3214,7 @@ static int
update_net_wm_type (MetaWindow *window) update_net_wm_type (MetaWindow *window)
{ {
Atom type; Atom type;
gint format; int format;
gulong n_atoms; gulong n_atoms;
gulong bytes_after; gulong bytes_after;
Atom *atoms; Atom *atoms;
@ -3482,7 +3559,7 @@ constrain_size (MetaWindow *window,
/* frame member variables should NEVER be used in here */ /* 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. */ /* Get the allowed size ranges, considering maximized, etc. */
fullw = window->screen->active_workspace->workarea.width; fullw = window->screen->active_workspace->workarea.width;