mirror of
https://github.com/yshui/picom.git
synced 2024-11-11 13:51:02 -05:00
Change fade callback function parameter
Change `win *` to `win **`, because a window could be freed by the callback, so we can set `*w` to NULL to communicate that. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
417744df14
commit
ab12467c3f
3 changed files with 52 additions and 65 deletions
|
@ -1162,7 +1162,7 @@ struct win {
|
||||||
/// Override value of window fade state. Set by D-Bus method calls.
|
/// Override value of window fade state. Set by D-Bus method calls.
|
||||||
switch_t fade_force;
|
switch_t fade_force;
|
||||||
/// Callback to be called after fading completed.
|
/// Callback to be called after fading completed.
|
||||||
void (*fade_callback) (session_t *ps, win *w);
|
void (*fade_callback) (session_t *ps, win **w);
|
||||||
|
|
||||||
// Frame-opacity-related members
|
// Frame-opacity-related members
|
||||||
/// Current window frame opacity. Affected by window opacity.
|
/// Current window frame opacity. Affected by window opacity.
|
||||||
|
|
101
src/compton.c
101
src/compton.c
|
@ -16,17 +16,18 @@
|
||||||
#include <xcb/xcb_image.h>
|
#include <xcb/xcb_image.h>
|
||||||
|
|
||||||
#include "compton.h"
|
#include "compton.h"
|
||||||
|
#ifdef CONFIG_OPENGL
|
||||||
|
#include "opengl.h"
|
||||||
|
#endif
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "x.h"
|
#include "x.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
configure_win(session_t *ps, xcb_configure_notify_event_t *ce);
|
finish_destroy_win(session_t *ps, win **_w);
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer,
|
configure_win(session_t *ps, xcb_configure_notify_event_t *ce);
|
||||||
int x, int y, int wid, int hei, xcb_render_fixed_t **blur_kerns,
|
|
||||||
XserverRegion reg_clip);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass);
|
get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass);
|
||||||
|
@ -103,18 +104,12 @@ recheck_focus(session_t *ps);
|
||||||
static bool
|
static bool
|
||||||
get_root_tile(session_t *ps);
|
get_root_tile(session_t *ps);
|
||||||
|
|
||||||
static void
|
|
||||||
finish_map_win(session_t *ps, win *w);
|
|
||||||
|
|
||||||
static double
|
static double
|
||||||
get_opacity_percent(win *w);
|
get_opacity_percent(win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
restack_win(session_t *ps, win *w, Window new_above);
|
restack_win(session_t *ps, win *w, Window new_above);
|
||||||
|
|
||||||
static void
|
|
||||||
destroy_callback(session_t *ps, win *w);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_ewmh_active_win(session_t *ps);
|
update_ewmh_active_win(session_t *ps);
|
||||||
|
|
||||||
|
@ -333,20 +328,34 @@ run_fade(session_t *ps, win *w, unsigned steps) {
|
||||||
*
|
*
|
||||||
* @param exec_callback whether the previous callback is to be executed
|
* @param exec_callback whether the previous callback is to be executed
|
||||||
*/
|
*/
|
||||||
void set_fade_callback(session_t *ps, win *w,
|
void set_fade_callback(session_t *ps, win **_w,
|
||||||
void (*callback) (session_t *ps, win *w), bool exec_callback) {
|
void (*callback) (session_t *ps, win **w), bool exec_callback) {
|
||||||
void (*old_callback) (session_t *ps, win *w) = w->fade_callback;
|
win *w = *_w;
|
||||||
|
void (*old_callback) (session_t *ps, win **w) = w->fade_callback;
|
||||||
|
|
||||||
w->fade_callback = callback;
|
w->fade_callback = callback;
|
||||||
// Must be the last line as the callback could destroy w!
|
// Must be the last line as the callback could destroy w!
|
||||||
if (exec_callback && old_callback) {
|
if (exec_callback && old_callback) {
|
||||||
old_callback(ps, w);
|
old_callback(ps, _w);
|
||||||
// Although currently no callback function affects window state on
|
// Although currently no callback function affects window state on
|
||||||
// next paint, it could, in the future
|
// next paint, it could, in the future
|
||||||
ps->idling = false;
|
ps->idling = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute fade callback of a window if fading finished.
|
||||||
|
* XXX should be in win.c
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
check_fade_fin(session_t *ps, win **_w) {
|
||||||
|
win *w = *_w;
|
||||||
|
if (w->fade_callback && w->opacity == w->opacity_tgt) {
|
||||||
|
// Must be the last line as the callback could destroy w!
|
||||||
|
set_fade_callback(ps, _w, NULL, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// === Shadows ===
|
// === Shadows ===
|
||||||
|
|
||||||
static double __attribute__((const))
|
static double __attribute__((const))
|
||||||
|
@ -1160,19 +1169,17 @@ paint_preprocess(session_t *ps, win *list) {
|
||||||
w->flags = 0;
|
w->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid setting w->to_paint if w is to be freed
|
|
||||||
bool destroyed = (w->opacity_tgt == w->opacity && w->destroyed);
|
|
||||||
|
|
||||||
if (to_paint) {
|
if (to_paint) {
|
||||||
w->prev_trans = t;
|
w->prev_trans = t;
|
||||||
t = w;
|
t = w;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(w->destroyed == (w->fade_callback == destroy_callback));
|
assert(w->destroyed == (w->fade_callback == finish_destroy_win));
|
||||||
check_fade_fin(ps, w);
|
check_fade_fin(ps, &w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!destroyed) {
|
// Avoid setting w->to_paint if w is to be freed
|
||||||
|
if (w) {
|
||||||
w->to_paint = to_paint;
|
w->to_paint = to_paint;
|
||||||
|
|
||||||
if (w->to_paint) {
|
if (w->to_paint) {
|
||||||
|
@ -1980,7 +1987,7 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
|
||||||
win *pprev = NULL;
|
win *pprev = NULL;
|
||||||
for (win *w = t; w; w = pprev) {
|
for (win *w = t; w; w = pprev) {
|
||||||
pprev = w->prev_trans;
|
pprev = w->prev_trans;
|
||||||
check_fade_fin(ps, w);
|
check_fade_fin(ps, &w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2023,6 +2030,15 @@ repair_win(session_t *ps, win *w) {
|
||||||
add_damage(ps, parts);
|
add_damage(ps, parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
finish_map_win(session_t *ps, win **_w) {
|
||||||
|
win *w = *_w;
|
||||||
|
w->in_openclose = false;
|
||||||
|
if (ps->o.no_fading_openclose) {
|
||||||
|
win_determine_fade(ps, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
map_win(session_t *ps, Window id) {
|
map_win(session_t *ps, Window id) {
|
||||||
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
xcb_connection_t *c = XGetXCBConnection(ps->dpy);
|
||||||
|
@ -2107,7 +2123,7 @@ map_win(session_t *ps, Window id) {
|
||||||
|
|
||||||
// Set fading state
|
// Set fading state
|
||||||
w->in_openclose = true;
|
w->in_openclose = true;
|
||||||
set_fade_callback(ps, w, finish_map_win, true);
|
set_fade_callback(ps, &w, finish_map_win, true);
|
||||||
win_determine_fade(ps, w);
|
win_determine_fade(ps, w);
|
||||||
|
|
||||||
win_determine_blur_background(ps, w);
|
win_determine_blur_background(ps, w);
|
||||||
|
@ -2130,17 +2146,9 @@ map_win(session_t *ps, Window id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
finish_map_win(session_t *ps, win *w) {
|
finish_unmap_win(session_t *ps, win **_w) {
|
||||||
w->in_openclose = false;
|
win *w = *_w;
|
||||||
if (ps->o.no_fading_openclose) {
|
|
||||||
win_determine_fade(ps, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
finish_unmap_win(session_t *ps, win *w) {
|
|
||||||
w->ever_damaged = false;
|
w->ever_damaged = false;
|
||||||
|
|
||||||
w->in_openclose = false;
|
w->in_openclose = false;
|
||||||
|
|
||||||
update_reg_ignore_expire(ps, w);
|
update_reg_ignore_expire(ps, w);
|
||||||
|
@ -2157,12 +2165,8 @@ finish_unmap_win(session_t *ps, win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unmap_callback(session_t *ps, win *w) {
|
unmap_win(session_t *ps, win **_w) {
|
||||||
finish_unmap_win(ps, w);
|
win *w = *_w;
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unmap_win(session_t *ps, win *w) {
|
|
||||||
if (!w || IsUnmapped == w->a.map_state) return;
|
if (!w || IsUnmapped == w->a.map_state) return;
|
||||||
|
|
||||||
if (w->destroyed) return;
|
if (w->destroyed) return;
|
||||||
|
@ -2179,7 +2183,7 @@ unmap_win(session_t *ps, win *w) {
|
||||||
|
|
||||||
// Fading out
|
// Fading out
|
||||||
w->flags |= WFLAG_OPCT_CHANGE;
|
w->flags |= WFLAG_OPCT_CHANGE;
|
||||||
set_fade_callback(ps, w, unmap_callback, false);
|
set_fade_callback(ps, _w, finish_unmap_win, false);
|
||||||
w->in_openclose = true;
|
w->in_openclose = true;
|
||||||
win_determine_fade(ps, w);
|
win_determine_fade(ps, w);
|
||||||
|
|
||||||
|
@ -2408,7 +2412,8 @@ circulate_win(session_t *ps, xcb_circulate_notify_event_t *ce) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
finish_destroy_win(session_t *ps, win *w) {
|
finish_destroy_win(session_t *ps, win **_w) {
|
||||||
|
win *w = *_w;
|
||||||
assert(w->destroyed);
|
assert(w->destroyed);
|
||||||
win **prev = NULL, *i = NULL;
|
win **prev = NULL, *i = NULL;
|
||||||
|
|
||||||
|
@ -2422,7 +2427,7 @@ finish_destroy_win(session_t *ps, win *w) {
|
||||||
printf_dbgf("(%#010lx \"%s\"): %p\n", w->id, w->name, w);
|
printf_dbgf("(%#010lx \"%s\"): %p\n", w->id, w->name, w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
finish_unmap_win(ps, w);
|
finish_unmap_win(ps, _w);
|
||||||
*prev = w->next;
|
*prev = w->next;
|
||||||
|
|
||||||
// Clear active_win if it's pointing to the destroyed window
|
// Clear active_win if it's pointing to the destroyed window
|
||||||
|
@ -2438,16 +2443,12 @@ finish_destroy_win(session_t *ps, win *w) {
|
||||||
w2->prev_trans = NULL;
|
w2->prev_trans = NULL;
|
||||||
|
|
||||||
free(w);
|
free(w);
|
||||||
|
*_w = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
destroy_callback(session_t *ps, win *w) {
|
|
||||||
finish_destroy_win(ps, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_win(session_t *ps, Window id) {
|
destroy_win(session_t *ps, Window id) {
|
||||||
win *w = find_win(ps, id);
|
win *w = find_win(ps, id);
|
||||||
|
@ -2457,7 +2458,7 @@ destroy_win(session_t *ps, Window id) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (w) {
|
if (w) {
|
||||||
unmap_win(ps, w);
|
unmap_win(ps, &w);
|
||||||
|
|
||||||
w->destroyed = true;
|
w->destroyed = true;
|
||||||
|
|
||||||
|
@ -2465,7 +2466,7 @@ destroy_win(session_t *ps, Window id) {
|
||||||
win_determine_fade(ps, w);
|
win_determine_fade(ps, w);
|
||||||
|
|
||||||
// Set fading callback
|
// Set fading callback
|
||||||
set_fade_callback(ps, w, destroy_callback, false);
|
set_fade_callback(ps, &w, finish_destroy_win, false);
|
||||||
|
|
||||||
#ifdef CONFIG_DBUS
|
#ifdef CONFIG_DBUS
|
||||||
// Send D-Bus signal
|
// Send D-Bus signal
|
||||||
|
@ -2905,7 +2906,7 @@ ev_unmap_notify(session_t *ps, xcb_unmap_notify_event_t *ev) {
|
||||||
win *w = find_win(ps, ev->window);
|
win *w = find_win(ps, ev->window);
|
||||||
|
|
||||||
if (w)
|
if (w)
|
||||||
unmap_win(ps, w);
|
unmap_win(ps, &w);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
|
|
|
@ -47,9 +47,6 @@ find_client_win(session_t *ps, Window w);
|
||||||
|
|
||||||
win *find_toplevel2(session_t *ps, Window wid);
|
win *find_toplevel2(session_t *ps, Window wid);
|
||||||
|
|
||||||
void set_fade_callback(session_t *ps, win *w,
|
|
||||||
void (*callback) (session_t *ps, win *w), bool exec_callback);
|
|
||||||
|
|
||||||
void map_win(session_t *ps, Window id);
|
void map_win(session_t *ps, Window id);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -348,17 +345,6 @@ wid_set_text_prop(session_t *ps, Window wid, Atom prop_atom, char *str) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute fade callback of a window if fading finished.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
check_fade_fin(session_t *ps, win *w) {
|
|
||||||
if (w->fade_callback && w->opacity == w->opacity_tgt) {
|
|
||||||
// Must be the last line as the callback could destroy w!
|
|
||||||
set_fade_callback(ps, w, NULL, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop listening for events on a particular window.
|
* Stop listening for events on a particular window.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue