yay. way way cleaner code for iconify animations. let people show/hide the frame logically and it will do everything except during animations the frame will show what it needs to for visual display.

This commit is contained in:
Dana Jansens 2007-05-05 16:53:48 +00:00
parent ac56fe1602
commit 378adaa94f
8 changed files with 28 additions and 70 deletions

View file

@ -1263,9 +1263,9 @@ void action_raiselower(union ActionData *data)
if (cit == c) break; if (cit == c) break;
if (client_normal(cit) == client_normal(c) && if (client_normal(cit) == client_normal(c) &&
cit->layer == c->layer && cit->layer == c->layer &&
frame_visible(cit->frame) && cit->frame->visible &&
!client_search_transient(c, cit)) !client_search_transient(c, cit))
{ {
if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) { if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) {
raise = TRUE; raise = TRUE;

View file

@ -2061,7 +2061,7 @@ static void client_change_wm_state(ObClient *self)
old = self->wmstate; old = self->wmstate;
if (self->shaded || self->iconic || !frame_visible(self->frame)) if (self->shaded || !self->frame->visible)
self->wmstate = IconicState; self->wmstate = IconicState;
else else
self->wmstate = NormalState; self->wmstate = NormalState;
@ -2724,27 +2724,10 @@ static void client_iconify_recursive(ObClient *self,
if (changed) { if (changed) {
client_change_state(self); client_change_state(self);
if (iconic) { if (ob_state() != OB_STATE_STARTING && config_animate_iconify)
if (ob_state() != OB_STATE_STARTING && config_animate_iconify) { frame_begin_iconify_animation(self->frame, iconic);
/* delay the showhide until the window is done the animation */ /* do this after starting the animation so it doesn't flash */
frame_begin_iconify_animation client_showhide(self);
(self->frame, iconic,
(ObFrameIconifyAnimateFunc)client_showhide, self);
/* but focus a new window now please */
focus_fallback(FALSE);
} else
client_showhide(self);
} else {
if (config_animate_iconify)
/* the animation will show the window when it is hidden,
but the window state needs to be adjusted after the
animation finishes, so call showhide when it's done to make
sure everything is updated appropriately
*/
frame_begin_iconify_animation
(self->frame, iconic,
(ObFrameIconifyAnimateFunc)client_showhide, self);
}
} }
/* iconify all direct transients, and deiconify all transients /* iconify all direct transients, and deiconify all transients
@ -3188,7 +3171,7 @@ gboolean client_can_focus(ObClient *self)
/* choose the correct target */ /* choose the correct target */
self = client_focus_target(self); self = client_focus_target(self);
if (!frame_visible(self->frame)) if (!self->frame->visible)
return FALSE; return FALSE;
if (!(self->can_focus || self->focus_notify)) if (!(self->can_focus || self->focus_notify))
@ -3221,7 +3204,7 @@ gboolean client_focus(ObClient *self)
self = client_focus_target(self); self = client_focus_target(self);
if (!client_can_focus(self)) { if (!client_can_focus(self)) {
if (!frame_visible(self->frame)) { if (!self->frame->visible) {
/* update the focus lists */ /* update the focus lists */
focus_order_to_top(self); focus_order_to_top(self);
} }
@ -3306,7 +3289,7 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
client_set_desktop(self, screen_desktop, FALSE); client_set_desktop(self, screen_desktop, FALSE);
else else
screen_set_desktop(self->desktop); screen_set_desktop(self->desktop);
} else if (!frame_visible(self->frame)) } else if (!self->frame->visible)
/* if its not visible for other reasons, then don't mess /* if its not visible for other reasons, then don't mess
with it */ with it */
return; return;
@ -3733,7 +3716,7 @@ ObClient* client_under_pointer()
for (it = stacking_list; it; it = g_list_next(it)) { for (it = stacking_list; it; it = g_list_next(it)) {
if (WINDOW_IS_CLIENT(it->data)) { if (WINDOW_IS_CLIENT(it->data)) {
ObClient *c = WINDOW_AS_CLIENT(it->data); ObClient *c = WINDOW_AS_CLIENT(it->data);
if (frame_visible(c->frame) && if (c->frame->visible &&
/* ignore all animating windows */ /* ignore all animating windows */
!frame_iconify_animating(c->frame) && !frame_iconify_animating(c->frame) &&
RECT_CONTAINS(c->frame->area, x, y)) RECT_CONTAINS(c->frame->area, x, y))

View file

@ -1386,7 +1386,7 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
{ {
/* the frame may not be "visible" but they can still click on it /* the frame may not be "visible" but they can still click on it
in the case where it is animating before disappearing */ in the case where it is animating before disappearing */
if (client && frame_visible(client->frame)) if (client && client->frame->visible)
mouse_event(client, e); mouse_event(client, e);
} else if (e->type == KeyPress) { } else if (e->type == KeyPress) {
keyboard_event((focus_cycle_target ? focus_cycle_target : keyboard_event((focus_cycle_target ? focus_cycle_target :

View file

@ -258,11 +258,12 @@ void frame_hide(ObFrame *self)
{ {
if (self->visible) { if (self->visible) {
self->visible = FALSE; self->visible = FALSE;
self->client->ignore_unmaps += 1; if (!frame_iconify_animating(self))
XUnmapWindow(ob_display, self->window);
/* we unmap the client itself so that we can get MapRequest /* we unmap the client itself so that we can get MapRequest
events, and because the ICCCM tells us to! */ events, and because the ICCCM tells us to! */
XUnmapWindow(ob_display, self->window);
XUnmapWindow(ob_display, self->client->window); XUnmapWindow(ob_display, self->client->window);
self->client->ignore_unmaps += 1;
} }
} }
@ -1121,13 +1122,12 @@ void frame_end_iconify_animation(ObFrame *self)
/* see if there is an animation going */ /* see if there is an animation going */
if (self->iconify_animation_going == 0) return; if (self->iconify_animation_going == 0) return;
/* call the callback when it's done */ if (!self->visible)
if (self->iconify_animation_cb) XUnmapWindow(ob_display, self->window);
self->iconify_animation_cb(self->iconify_animation_data);
/* we're not animating any more ! */ /* we're not animating any more ! */
self->iconify_animation_going = 0; self->iconify_animation_going = 0;
/* move after the callback for the animation ending */
XMoveResizeWindow(ob_display, self->window, XMoveResizeWindow(ob_display, self->window,
self->area.x, self->area.y, self->area.x, self->area.y,
self->area.width - self->bwidth * 2, self->area.width - self->bwidth * 2,
@ -1135,9 +1135,7 @@ void frame_end_iconify_animation(ObFrame *self)
XFlush(ob_display); XFlush(ob_display);
} }
void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying, void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
ObFrameIconifyAnimateFunc callback,
gpointer data)
{ {
gulong time; gulong time;
gboolean new_anim = FALSE; gboolean new_anim = FALSE;
@ -1146,10 +1144,8 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying,
/* if there is no titlebar, just don't animate for now /* if there is no titlebar, just don't animate for now
XXX it would be nice tho.. */ XXX it would be nice tho.. */
if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR)) { if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR))
if (callback) callback(data);
return; return;
}
/* get the current time */ /* get the current time */
g_get_current_time(&now); g_get_current_time(&now);
@ -1167,9 +1163,6 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying,
new_anim = TRUE; new_anim = TRUE;
self->iconify_animation_going = iconifying ? 1 : -1; self->iconify_animation_going = iconifying ? 1 : -1;
self->iconify_animation_cb = callback;
self->iconify_animation_data = data;
/* set the ending time */ /* set the ending time */
if (set_end) { if (set_end) {
self->iconify_animation_end.tv_sec = now.tv_sec; self->iconify_animation_end.tv_sec = now.tv_sec;
@ -1188,14 +1181,8 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying,
/* do the first step */ /* do the first step */
frame_animate_iconify(self); frame_animate_iconify(self);
/* show it during the animation even if it is not "visible" */
if (!self->visible) if (!self->visible)
frame_show(self); XMapWindow(ob_display, self->window);
} }
} }
gboolean frame_visible(ObFrame *self)
{
/* if it is animating back from iconic state then it is considered
visible. but if it is iconifying then it is not visible. */
return self->visible && self->iconify_animation_going <= 0;
}

View file

@ -77,9 +77,6 @@ struct _ObFrame
Strut size; Strut size;
Rect area; Rect area;
/*! Is the frame visible? Don't read this directly ! Use frame_visible()
instead, because that takes into account if the frame is visible but
animating to the iconic (invisible) state. */
gboolean visible; gboolean visible;
guint decorations; guint decorations;
@ -154,8 +151,6 @@ struct _ObFrame
*/ */
gint iconify_animation_going; gint iconify_animation_going;
GTimeVal iconify_animation_end; GTimeVal iconify_animation_end;
ObFrameIconifyAnimateFunc iconify_animation_cb;
gpointer iconify_animation_data;
}; };
ObFrame *frame_new(struct _ObClient *c); ObFrame *frame_new(struct _ObClient *c);
@ -195,15 +190,9 @@ void frame_flash_stop(ObFrame *self);
/*! Start an animation for iconifying or restoring a frame. The callback /*! Start an animation for iconifying or restoring a frame. The callback
will be called when the animation finishes. But if another animation is will be called when the animation finishes. But if another animation is
started in the meantime, the callback will never get called. */ started in the meantime, the callback will never get called. */
void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying, void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying);
ObFrameIconifyAnimateFunc callback,
gpointer data);
void frame_end_iconify_animation(ObFrame *self); void frame_end_iconify_animation(ObFrame *self);
/* Returns true if the frame is visible (but false if it is only visible
because it is animating */
gboolean frame_visible(ObFrame *self);
#define frame_iconify_animating(f) (f->iconify_animation_going != 0) #define frame_iconify_animating(f) (f->iconify_animation_going != 0)
#endif #endif

View file

@ -153,7 +153,7 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
moving = (cnr == prop_atoms.net_wm_moveresize_move || moving = (cnr == prop_atoms.net_wm_moveresize_move ||
cnr == prop_atoms.net_wm_moveresize_move_keyboard); cnr == prop_atoms.net_wm_moveresize_move_keyboard);
if (moveresize_in_progress || !frame_visible(c->frame) || if (moveresize_in_progress || !c->frame->visible ||
!(moving ? !(moving ?
(c->functions & OB_CLIENT_FUNC_MOVE) : (c->functions & OB_CLIENT_FUNC_MOVE) :
(c->functions & OB_CLIENT_FUNC_RESIZE))) (c->functions & OB_CLIENT_FUNC_RESIZE)))

View file

@ -251,8 +251,7 @@ typedef enum
} ObSmartType; } ObSmartType;
#define SMART_IGNORE(placer, c) \ #define SMART_IGNORE(placer, c) \
(placer == c || c->shaded || !client_normal(c) || \ (placer == c || c->shaded || !client_normal(c) || !c->frame->visible || \
!frame_visible(c->frame) || \
(c->desktop != DESKTOP_ALL && \ (c->desktop != DESKTOP_ALL && \
c->desktop != (placer->desktop == DESKTOP_ALL ? \ c->desktop != (placer->desktop == DESKTOP_ALL ? \
screen_desktop : placer->desktop))) screen_desktop : placer->desktop)))

View file

@ -57,7 +57,7 @@ void resist_move_windows(ObClient *c, gint *x, gint *y)
target = it->data; target = it->data;
/* don't snap to self or non-visibles */ /* don't snap to self or non-visibles */
if (!frame_visible(target->frame) || target == c) continue; if (!target->frame->visible || target == c) continue;
/* don't snap to windows in layers beneath */ /* don't snap to windows in layers beneath */
if(target->layer < c->layer && !config_resist_layers_below) if(target->layer < c->layer && !config_resist_layers_below)
@ -199,7 +199,7 @@ void resist_size_windows(ObClient *c, gint *w, gint *h, ObCorner corn)
target = it->data; target = it->data;
/* don't snap to invisibles or ourself */ /* don't snap to invisibles or ourself */
if (!frame_visible(target->frame) || target == c) continue; if (!target->frame->visible || target == c) continue;
/* don't snap to windows in layers beneath */ /* don't snap to windows in layers beneath */
if(target->layer < c->layer && !config_resist_layers_below) if(target->layer < c->layer && !config_resist_layers_below)