Merge pull request #364 from tryone144/fix/blur-background-fixed
Experimental backends: fade/hide blur-texture for transparent windows
This commit is contained in:
commit
3ad4ce9f77
|
@ -52,3 +52,5 @@ doxygen/
|
||||||
/src/backtrace-symbols.[ch]
|
/src/backtrace-symbols.[ch]
|
||||||
/compton*.trace
|
/compton*.trace
|
||||||
*.orig
|
*.orig
|
||||||
|
/tests/log
|
||||||
|
/tests/testcases/__pycache__/
|
||||||
|
|
|
@ -204,16 +204,34 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||||
// itself is not opaque, only the frame is.
|
// itself is not opaque, only the frame is.
|
||||||
|
|
||||||
double blur_opacity = 1;
|
double blur_opacity = 1;
|
||||||
if (w->state == WSTATE_MAPPING) {
|
if (w->opacity < (1.0 / MAX_ALPHA)) {
|
||||||
|
// Hide blur for fully transparent windows.
|
||||||
|
blur_opacity = 0;
|
||||||
|
} else if (w->state == WSTATE_MAPPING) {
|
||||||
// Gradually increase the blur intensity during
|
// Gradually increase the blur intensity during
|
||||||
// fading in.
|
// fading in.
|
||||||
|
assert(w->opacity <= w->opacity_target);
|
||||||
blur_opacity = w->opacity / w->opacity_target;
|
blur_opacity = w->opacity / w->opacity_target;
|
||||||
} else if (w->state == WSTATE_UNMAPPING ||
|
} else if (w->state == WSTATE_UNMAPPING ||
|
||||||
w->state == WSTATE_DESTROYING) {
|
w->state == WSTATE_DESTROYING) {
|
||||||
// Gradually decrease the blur intensity during
|
// Gradually decrease the blur intensity during
|
||||||
// fading out.
|
// fading out.
|
||||||
blur_opacity =
|
assert(w->opacity <= w->opacity_target_old);
|
||||||
w->opacity / win_calc_opacity_target(ps, w, true);
|
blur_opacity = w->opacity / w->opacity_target_old;
|
||||||
|
} else if (w->state == WSTATE_FADING) {
|
||||||
|
if (w->opacity < w->opacity_target &&
|
||||||
|
w->opacity_target_old < (1.0 / MAX_ALPHA)) {
|
||||||
|
// Gradually increase the blur intensity during
|
||||||
|
// fading in.
|
||||||
|
assert(w->opacity <= w->opacity_target);
|
||||||
|
blur_opacity = w->opacity / w->opacity_target;
|
||||||
|
} else if (w->opacity > w->opacity_target &&
|
||||||
|
w->opacity_target < (1.0 / MAX_ALPHA)) {
|
||||||
|
// Gradually decrease the blur intensity during
|
||||||
|
// fading out.
|
||||||
|
assert(w->opacity <= w->opacity_target_old);
|
||||||
|
blur_opacity = w->opacity / w->opacity_target_old;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(blur_opacity >= 0 && blur_opacity <= 1);
|
assert(blur_opacity >= 0 && blur_opacity <= 1);
|
||||||
|
|
||||||
|
|
11
src/event.c
11
src/event.c
|
@ -287,7 +287,7 @@ static inline void ev_map_notify(session_t *ps, xcb_map_notify_event_t *ev) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
win_queue_update(w, WIN_UPDATE_MAP);
|
win_set_flags(w, WIN_FLAGS_MAPPED);
|
||||||
|
|
||||||
// FocusIn/Out may be ignored when the window is unmapped, so we must
|
// FocusIn/Out may be ignored when the window is unmapped, so we must
|
||||||
// recheck focus here
|
// recheck focus here
|
||||||
|
@ -482,14 +482,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
win_update_opacity_prop(ps, w);
|
win_update_opacity_prop(ps, w);
|
||||||
// we cannot receive OPACITY change when window is destroyed
|
// we cannot receive OPACITY change when window is destroyed
|
||||||
assert(w->state != WSTATE_DESTROYING);
|
assert(w->state != WSTATE_DESTROYING);
|
||||||
w->opacity_target = win_calc_opacity_target(ps, w, false);
|
win_update_opacity_target(ps, w);
|
||||||
if (w->state == WSTATE_MAPPED) {
|
|
||||||
// See the winstate_t transition table
|
|
||||||
w->state = WSTATE_FADING;
|
|
||||||
}
|
|
||||||
if (!ps->redirected) {
|
|
||||||
CHECK(!win_skip_fading(ps, w));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/picom.c
23
src/picom.c
|
@ -1309,12 +1309,6 @@ static void handle_new_windows(session_t *ps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void refresh_windows(session_t *ps) {
|
static void refresh_windows(session_t *ps) {
|
||||||
win_stack_foreach_managed_safe(w, &ps->window_stack) {
|
|
||||||
win_process_updates(ps, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void refresh_stale_images(session_t *ps) {
|
|
||||||
win_stack_foreach_managed(w, &ps->window_stack) {
|
win_stack_foreach_managed(w, &ps->window_stack) {
|
||||||
win_process_flags(ps, w);
|
win_process_flags(ps, w);
|
||||||
}
|
}
|
||||||
|
@ -1351,7 +1345,13 @@ static void handle_pending_updates(EV_P_ struct session *ps) {
|
||||||
// Call fill_win on new windows
|
// Call fill_win on new windows
|
||||||
handle_new_windows(ps);
|
handle_new_windows(ps);
|
||||||
|
|
||||||
// Process window updates
|
// Handle screen changes
|
||||||
|
// This HAS TO be called before refresh_windows, as handle_root_flags
|
||||||
|
// could call configure_root, which will release images and mark them
|
||||||
|
// stale.
|
||||||
|
handle_root_flags(ps);
|
||||||
|
|
||||||
|
// Process window flags
|
||||||
refresh_windows(ps);
|
refresh_windows(ps);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1363,15 +1363,6 @@ static void handle_pending_updates(EV_P_ struct session *ps) {
|
||||||
free(r);
|
free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle screen changes
|
|
||||||
// This HAS TO be called before refresh_stale_images, as handle_root_flags
|
|
||||||
// could call configure_root, which will release images and mark them
|
|
||||||
// stale.
|
|
||||||
handle_root_flags(ps);
|
|
||||||
|
|
||||||
// Refresh pixmaps and shadows
|
|
||||||
refresh_stale_images(ps);
|
|
||||||
|
|
||||||
e = xcb_request_check(ps->c, xcb_ungrab_server_checked(ps->c));
|
e = xcb_request_check(ps->c, xcb_ungrab_server_checked(ps->c));
|
||||||
if (e) {
|
if (e) {
|
||||||
log_fatal_x_error(e, "failed to ungrab x server");
|
log_fatal_x_error(e, "failed to ungrab x server");
|
||||||
|
|
201
src/win.c
201
src/win.c
|
@ -46,9 +46,6 @@
|
||||||
// TODO Make more window states internal
|
// TODO Make more window states internal
|
||||||
struct managed_win_internal {
|
struct managed_win_internal {
|
||||||
struct managed_win base;
|
struct managed_win base;
|
||||||
|
|
||||||
/// A bit mask of unhandled window updates
|
|
||||||
uint_fast32_t pending_updates;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OPAQUE (0xffffffff)
|
#define OPAQUE (0xffffffff)
|
||||||
|
@ -247,6 +244,7 @@ static inline void win_release_pixmap(backend_t *base, struct managed_win *w) {
|
||||||
if (w->win_image) {
|
if (w->win_image) {
|
||||||
base->ops->release_image(base, w->win_image);
|
base->ops->release_image(base, w->win_image);
|
||||||
w->win_image = NULL;
|
w->win_image = NULL;
|
||||||
|
// Bypassing win_set_flags, because `w` might have been destroyed
|
||||||
w->flags |= WIN_FLAGS_PIXMAP_NONE;
|
w->flags |= WIN_FLAGS_PIXMAP_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,6 +254,7 @@ static inline void win_release_shadow(backend_t *base, struct managed_win *w) {
|
||||||
if (w->shadow_image) {
|
if (w->shadow_image) {
|
||||||
base->ops->release_image(base, w->shadow_image);
|
base->ops->release_image(base, w->shadow_image);
|
||||||
w->shadow_image = NULL;
|
w->shadow_image = NULL;
|
||||||
|
// Bypassing win_set_flags, because `w` might have been destroyed
|
||||||
w->flags |= WIN_FLAGS_SHADOW_NONE;
|
w->flags |= WIN_FLAGS_SHADOW_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,11 +275,11 @@ static inline bool win_bind_pixmap(struct backend_base *b, struct managed_win *w
|
||||||
b->ops->bind_pixmap(b, pixmap, x_get_visual_info(b->c, w->a.visual), true);
|
b->ops->bind_pixmap(b, pixmap, x_get_visual_info(b->c, w->a.visual), true);
|
||||||
if (!w->win_image) {
|
if (!w->win_image) {
|
||||||
log_error("Failed to bind pixmap");
|
log_error("Failed to bind pixmap");
|
||||||
w->flags |= WIN_FLAGS_IMAGE_ERROR;
|
win_set_flags(w, WIN_FLAGS_IMAGE_ERROR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->flags &= ~WIN_FLAGS_PIXMAP_NONE;
|
win_clear_flags(w, WIN_FLAGS_PIXMAP_NONE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,13 +293,13 @@ bool win_bind_shadow(struct backend_base *b, struct managed_win *w, struct color
|
||||||
log_error("Failed to bind shadow image, shadow will be disabled for "
|
log_error("Failed to bind shadow image, shadow will be disabled for "
|
||||||
"%#010x (%s)",
|
"%#010x (%s)",
|
||||||
w->base.id, w->name);
|
w->base.id, w->name);
|
||||||
w->flags |= WIN_FLAGS_SHADOW_NONE;
|
win_set_flags(w, WIN_FLAGS_SHADOW_NONE);
|
||||||
w->shadow = false;
|
w->shadow = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("New shadow for %#010x (%s)", w->base.id, w->name);
|
log_debug("New shadow for %#010x (%s)", w->base.id, w->name);
|
||||||
w->flags &= ~WIN_FLAGS_SHADOW_NONE;
|
win_clear_flags(w, WIN_FLAGS_SHADOW_NONE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,40 +309,38 @@ void win_release_images(struct backend_base *backend, struct managed_win *w) {
|
||||||
// But if we are not releasing any images anyway, we don't care about the stale
|
// But if we are not releasing any images anyway, we don't care about the stale
|
||||||
// flags.
|
// flags.
|
||||||
|
|
||||||
if ((w->flags & WIN_FLAGS_PIXMAP_NONE) == 0) {
|
if (!win_check_flags_all(w, WIN_FLAGS_PIXMAP_NONE)) {
|
||||||
assert((w->flags & WIN_FLAGS_PIXMAP_STALE) == 0);
|
assert(!win_check_flags_all(w, WIN_FLAGS_PIXMAP_STALE));
|
||||||
win_release_pixmap(backend, w);
|
win_release_pixmap(backend, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((w->flags & WIN_FLAGS_SHADOW_NONE) == 0) {
|
if (!win_check_flags_all(w, WIN_FLAGS_SHADOW_NONE)) {
|
||||||
assert((w->flags & WIN_FLAGS_SHADOW_STALE) == 0);
|
assert(!win_check_flags_all(w, WIN_FLAGS_SHADOW_STALE));
|
||||||
win_release_shadow(backend, w);
|
win_release_shadow(backend, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void win_process_flags(session_t *ps, struct managed_win *w) {
|
void win_process_flags(session_t *ps, struct managed_win *w) {
|
||||||
// Make sure all pending window updates are processed before this. Making this
|
if (win_check_flags_all(w, WIN_FLAGS_MAPPED)) {
|
||||||
// assumption simplifies some checks (e.g. whether window is mapped)
|
map_win_start(ps, w);
|
||||||
assert(((struct managed_win_internal *)w)->pending_updates == 0);
|
|
||||||
|
|
||||||
if (!w->flags || (w->flags & WIN_FLAGS_IMAGE_ERROR) != 0) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
win_clear_flags(w, WIN_FLAGS_MAPPED);
|
||||||
|
|
||||||
// Not a loop
|
// Not a loop
|
||||||
while ((w->flags & WIN_FLAGS_IMAGES_STALE) != 0) {
|
while (win_check_flags_any(w, WIN_FLAGS_IMAGES_STALE) &&
|
||||||
|
!win_check_flags_all(w, WIN_FLAGS_IMAGE_ERROR)) {
|
||||||
// Image needs to be updated, update it.
|
// Image needs to be updated, update it.
|
||||||
if (!ps->backend_data) {
|
if (!ps->backend_data) {
|
||||||
// We are using legacy backend, nothing to do here.
|
// We are using legacy backend, nothing to do here.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((w->flags & WIN_FLAGS_PIXMAP_STALE) != 0) {
|
if (win_check_flags_all(w, WIN_FLAGS_PIXMAP_STALE)) {
|
||||||
// Check to make sure the window is still mapped, otherwise we
|
// Check to make sure the window is still mapped, otherwise we
|
||||||
// won't be able to rebind pixmap after releasing it, yet we might
|
// won't be able to rebind pixmap after releasing it, yet we might
|
||||||
// still need the pixmap for rendering.
|
// still need the pixmap for rendering.
|
||||||
assert(w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING);
|
assert(w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING);
|
||||||
if ((w->flags & WIN_FLAGS_PIXMAP_NONE) == 0) {
|
if (!win_check_flags_all(w, WIN_FLAGS_PIXMAP_NONE)) {
|
||||||
// Must release images first, otherwise breaks
|
// Must release images first, otherwise breaks
|
||||||
// NVIDIA driver
|
// NVIDIA driver
|
||||||
win_release_pixmap(ps->backend_data, w);
|
win_release_pixmap(ps->backend_data, w);
|
||||||
|
@ -351,8 +348,8 @@ void win_process_flags(session_t *ps, struct managed_win *w) {
|
||||||
win_bind_pixmap(ps->backend_data, w);
|
win_bind_pixmap(ps->backend_data, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((w->flags & WIN_FLAGS_SHADOW_STALE) != 0) {
|
if (win_check_flags_all(w, WIN_FLAGS_SHADOW_STALE)) {
|
||||||
if ((w->flags & WIN_FLAGS_SHADOW_NONE) == 0) {
|
if (!win_check_flags_all(w, WIN_FLAGS_SHADOW_NONE)) {
|
||||||
win_release_shadow(ps->backend_data, w);
|
win_release_shadow(ps->backend_data, w);
|
||||||
}
|
}
|
||||||
if (w->shadow) {
|
if (w->shadow) {
|
||||||
|
@ -370,7 +367,7 @@ void win_process_flags(session_t *ps, struct managed_win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear stale image flags
|
// Clear stale image flags
|
||||||
w->flags &= ~WIN_FLAGS_IMAGES_STALE;
|
win_clear_flags(w, WIN_FLAGS_IMAGES_STALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -582,18 +579,17 @@ winmode_t win_calc_mode(const struct managed_win *w) {
|
||||||
*
|
*
|
||||||
* @param ps current session
|
* @param ps current session
|
||||||
* @param w struct _win object representing the window
|
* @param w struct _win object representing the window
|
||||||
* @param ignore_state whether window state should be ignored in opacity calculation
|
|
||||||
*
|
*
|
||||||
* @return target opacity
|
* @return target opacity
|
||||||
*/
|
*/
|
||||||
double win_calc_opacity_target(session_t *ps, const struct managed_win *w, bool ignore_state) {
|
double win_calc_opacity_target(session_t *ps, const struct managed_win *w) {
|
||||||
double opacity = 1;
|
double opacity = 1;
|
||||||
|
|
||||||
if (w->state == WSTATE_UNMAPPED && !ignore_state) {
|
if (w->state == WSTATE_UNMAPPED) {
|
||||||
// be consistent
|
// be consistent
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((w->state == WSTATE_UNMAPPING || w->state == WSTATE_DESTROYING) && !ignore_state) {
|
if (w->state == WSTATE_UNMAPPING || w->state == WSTATE_DESTROYING) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Try obeying opacity property and window type opacity firstly
|
// Try obeying opacity property and window type opacity firstly
|
||||||
|
@ -694,7 +690,7 @@ static void win_set_shadow(session_t *ps, struct managed_win *w, bool shadow_new
|
||||||
w->shadow = shadow_new;
|
w->shadow = shadow_new;
|
||||||
assert(!w->shadow_image);
|
assert(!w->shadow_image);
|
||||||
assert(!w->win_image);
|
assert(!w->win_image);
|
||||||
assert(w->flags & WIN_FLAGS_IMAGES_NONE);
|
assert(win_check_flags_all(w, WIN_FLAGS_IMAGES_NONE));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,14 +716,14 @@ static void win_set_shadow(session_t *ps, struct managed_win *w, bool shadow_new
|
||||||
// asserting the existence of the shadow image.
|
// asserting the existence of the shadow image.
|
||||||
if (w->shadow) {
|
if (w->shadow) {
|
||||||
// Mark the new extents as damaged if the shadow is added
|
// Mark the new extents as damaged if the shadow is added
|
||||||
assert(!w->shadow_image || (w->flags & WIN_FLAGS_SHADOW_STALE) ||
|
assert(!w->shadow_image || win_check_flags_all(w, WIN_FLAGS_SHADOW_STALE) ||
|
||||||
!ps->o.experimental_backends);
|
!ps->o.experimental_backends);
|
||||||
pixman_region32_clear(&extents);
|
pixman_region32_clear(&extents);
|
||||||
win_extents(w, &extents);
|
win_extents(w, &extents);
|
||||||
add_damage_from_win(ps, w);
|
add_damage_from_win(ps, w);
|
||||||
} else {
|
} else {
|
||||||
// Mark the old extents as damaged if the shadow is removed
|
// Mark the old extents as damaged if the shadow is removed
|
||||||
assert(w->shadow_image || (w->flags & WIN_FLAGS_SHADOW_STALE) ||
|
assert(w->shadow_image || win_check_flags_all(w, WIN_FLAGS_SHADOW_STALE) ||
|
||||||
!ps->o.experimental_backends);
|
!ps->o.experimental_backends);
|
||||||
add_damage(ps, &extents);
|
add_damage(ps, &extents);
|
||||||
}
|
}
|
||||||
|
@ -737,7 +733,7 @@ static void win_set_shadow(session_t *ps, struct managed_win *w, bool shadow_new
|
||||||
// Delayed update of shadow image
|
// Delayed update of shadow image
|
||||||
// By setting WIN_FLAGS_SHADOW_STALE, we ask win_process_flags to re-create or
|
// By setting WIN_FLAGS_SHADOW_STALE, we ask win_process_flags to re-create or
|
||||||
// release the shaodw in based on whether w->shadow is set.
|
// release the shaodw in based on whether w->shadow is set.
|
||||||
w->flags |= WIN_FLAGS_SHADOW_STALE;
|
win_set_flags(w, WIN_FLAGS_SHADOW_STALE);
|
||||||
ps->pending_updates = true;
|
ps->pending_updates = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,18 +911,7 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) {
|
||||||
w->unredir_if_possible_excluded =
|
w->unredir_if_possible_excluded =
|
||||||
c2_match(ps, w, ps->o.unredir_if_possible_blacklist, NULL);
|
c2_match(ps, w, ps->o.unredir_if_possible_blacklist, NULL);
|
||||||
|
|
||||||
auto opacity_target_old = w->opacity_target;
|
win_update_opacity_target(ps, w);
|
||||||
w->opacity_target = win_calc_opacity_target(ps, w, false);
|
|
||||||
if (opacity_target_old != w->opacity_target && w->state == WSTATE_MAPPED) {
|
|
||||||
// Only MAPPED can transition to FADING
|
|
||||||
assert(w->opacity == opacity_target_old);
|
|
||||||
w->state = WSTATE_FADING;
|
|
||||||
log_debug("Window %#010x (%s) opactiy %f, opacity target %f", w->base.id,
|
|
||||||
w->name, w->opacity, w->opacity_target);
|
|
||||||
if (!ps->redirected) {
|
|
||||||
CHECK(!win_skip_fading(ps, w));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w->reg_ignore_valid = false;
|
w->reg_ignore_valid = false;
|
||||||
}
|
}
|
||||||
|
@ -945,7 +930,7 @@ void win_on_win_size_change(session_t *ps, struct managed_win *w) {
|
||||||
// Invalidate the shadow we built
|
// Invalidate the shadow we built
|
||||||
if (w->state == WSTATE_MAPPED || w->state == WSTATE_MAPPING ||
|
if (w->state == WSTATE_MAPPED || w->state == WSTATE_MAPPING ||
|
||||||
w->state == WSTATE_FADING) {
|
w->state == WSTATE_FADING) {
|
||||||
w->flags |= WIN_FLAGS_IMAGES_STALE;
|
win_set_flags(w, WIN_FLAGS_IMAGES_STALE);
|
||||||
ps->pending_updates = true;
|
ps->pending_updates = true;
|
||||||
} else {
|
} else {
|
||||||
assert(w->state == WSTATE_UNMAPPED);
|
assert(w->state == WSTATE_UNMAPPED);
|
||||||
|
@ -1301,7 +1286,6 @@ struct win *fill_win(session_t *ps, struct win *w) {
|
||||||
// Allocate and initialize the new win structure
|
// Allocate and initialize the new win structure
|
||||||
auto new_internal = cmalloc(struct managed_win_internal);
|
auto new_internal = cmalloc(struct managed_win_internal);
|
||||||
auto new = (struct managed_win *)new_internal;
|
auto new = (struct managed_win *)new_internal;
|
||||||
new_internal->pending_updates = 0;
|
|
||||||
|
|
||||||
// Fill structure
|
// Fill structure
|
||||||
// We only need to initialize the part that are not initialized
|
// We only need to initialize the part that are not initialized
|
||||||
|
@ -1599,7 +1583,7 @@ void win_update_bounding_shape(session_t *ps, struct managed_win *w) {
|
||||||
// Note we only do this when screen is redirected, because
|
// Note we only do this when screen is redirected, because
|
||||||
// otherwise win_data is not valid
|
// otherwise win_data is not valid
|
||||||
assert(w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING);
|
assert(w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING);
|
||||||
w->flags |= WIN_FLAGS_IMAGES_STALE;
|
win_set_flags(w, WIN_FLAGS_IMAGES_STALE);
|
||||||
ps->pending_updates = true;
|
ps->pending_updates = true;
|
||||||
}
|
}
|
||||||
free_paint(ps, &w->paint);
|
free_paint(ps, &w->paint);
|
||||||
|
@ -1713,7 +1697,7 @@ static void unmap_win_finish(session_t *ps, struct managed_win *w) {
|
||||||
free_paint(ps, &w->shadow_paint);
|
free_paint(ps, &w->shadow_paint);
|
||||||
|
|
||||||
// Try again at binding images when the window is mapped next time
|
// Try again at binding images when the window is mapped next time
|
||||||
w->flags &= ~WIN_FLAGS_IMAGE_ERROR;
|
win_clear_flags(w, WIN_FLAGS_IMAGE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish the destruction of a window (e.g. after fading has finished).
|
/// Finish the destruction of a window (e.g. after fading has finished).
|
||||||
|
@ -1886,14 +1870,15 @@ bool destroy_win_start(session_t *ps, struct win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->managed) {
|
if (w->managed) {
|
||||||
|
// Clear PIXMAP_STALE flag, since the window is destroyed there is no
|
||||||
|
// pixmap available so STALE doesn't make sense.
|
||||||
|
// Do this before changing the window state to destroying
|
||||||
|
win_clear_flags(mw, WIN_FLAGS_PIXMAP_STALE);
|
||||||
|
|
||||||
// Update state flags of a managed window
|
// Update state flags of a managed window
|
||||||
mw->state = WSTATE_DESTROYING;
|
mw->state = WSTATE_DESTROYING;
|
||||||
mw->a.map_state = XCB_MAP_STATE_UNMAPPED;
|
mw->a.map_state = XCB_MAP_STATE_UNMAPPED;
|
||||||
mw->in_openclose = true;
|
mw->in_openclose = true;
|
||||||
|
|
||||||
// Clear PIXMAP_STALE flag, since the window is destroyed there is no
|
|
||||||
// pixmap available so STALE doesn't make sense.
|
|
||||||
mw->flags &= ~WIN_FLAGS_PIXMAP_STALE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't need win_ev_stop because the window is gone anyway
|
// don't need win_ev_stop because the window is gone anyway
|
||||||
|
@ -1913,7 +1898,6 @@ bool destroy_win_start(session_t *ps, struct win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmap_win_start(session_t *ps, struct managed_win *w) {
|
void unmap_win_start(session_t *ps, struct managed_win *w) {
|
||||||
auto internal_w = (struct managed_win_internal *)w;
|
|
||||||
assert(w);
|
assert(w);
|
||||||
assert(w->base.managed);
|
assert(w->base.managed);
|
||||||
assert(w->a._class != XCB_WINDOW_CLASS_INPUT_ONLY);
|
assert(w->a._class != XCB_WINDOW_CLASS_INPUT_ONLY);
|
||||||
|
@ -1926,8 +1910,9 @@ void unmap_win_start(session_t *ps, struct managed_win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(w->state == WSTATE_UNMAPPING || w->state == WSTATE_UNMAPPED)) {
|
if (unlikely(w->state == WSTATE_UNMAPPING || w->state == WSTATE_UNMAPPED)) {
|
||||||
if (internal_w->pending_updates & WIN_UPDATE_MAP) {
|
if (win_check_flags_all(w, WIN_FLAGS_MAPPED)) {
|
||||||
internal_w->pending_updates &= ~(unsigned long)WIN_UPDATE_MAP;
|
// Clear the pending map as this window is now unmapped
|
||||||
|
win_clear_flags(w, WIN_FLAGS_MAPPED);
|
||||||
} else {
|
} else {
|
||||||
log_warn("Trying to unmapping an already unmapped window %#010x "
|
log_warn("Trying to unmapping an already unmapped window %#010x "
|
||||||
"\"%s\"",
|
"\"%s\"",
|
||||||
|
@ -1942,11 +1927,12 @@ void unmap_win_start(session_t *ps, struct managed_win *w) {
|
||||||
|
|
||||||
w->a.map_state = XCB_MAP_STATE_UNMAPPED;
|
w->a.map_state = XCB_MAP_STATE_UNMAPPED;
|
||||||
w->state = WSTATE_UNMAPPING;
|
w->state = WSTATE_UNMAPPING;
|
||||||
w->opacity_target = win_calc_opacity_target(ps, w, false);
|
w->opacity_target_old = fmax(w->opacity_target, w->opacity_target_old);
|
||||||
|
w->opacity_target = win_calc_opacity_target(ps, w);
|
||||||
|
|
||||||
// Clear PIXMAP_STALE flag, since the window is unmapped there is no pixmap
|
// Clear PIXMAP_STALE flag, since the window is unmapped there is no pixmap
|
||||||
// available so STALE doesn't make sense.
|
// available so STALE doesn't make sense.
|
||||||
w->flags &= ~WIN_FLAGS_PIXMAP_STALE;
|
win_clear_flags(w, WIN_FLAGS_PIXMAP_STALE);
|
||||||
|
|
||||||
// don't care about properties anymore
|
// don't care about properties anymore
|
||||||
win_ev_stop(ps, &w->base);
|
win_ev_stop(ps, &w->base);
|
||||||
|
@ -2053,8 +2039,7 @@ void map_win_start(session_t *ps, struct managed_win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(w->state == WSTATE_UNMAPPED);
|
assert(w->state == WSTATE_UNMAPPED);
|
||||||
assert((w->flags & WIN_FLAGS_IMAGES_NONE) == WIN_FLAGS_IMAGES_NONE ||
|
assert(win_check_flags_all(w, WIN_FLAGS_IMAGES_NONE) || !ps->o.experimental_backends);
|
||||||
!ps->o.experimental_backends);
|
|
||||||
|
|
||||||
// We stopped processing window size change when we were unmapped, refresh the
|
// We stopped processing window size change when we were unmapped, refresh the
|
||||||
// size of the window
|
// size of the window
|
||||||
|
@ -2127,7 +2112,8 @@ void map_win_start(session_t *ps, struct managed_win *w) {
|
||||||
// XXX We need to make sure that win_data is available
|
// XXX We need to make sure that win_data is available
|
||||||
// iff `state` is MAPPED
|
// iff `state` is MAPPED
|
||||||
w->state = WSTATE_MAPPING;
|
w->state = WSTATE_MAPPING;
|
||||||
w->opacity_target = win_calc_opacity_target(ps, w, false);
|
w->opacity_target_old = 0;
|
||||||
|
w->opacity_target = win_calc_opacity_target(ps, w);
|
||||||
|
|
||||||
log_debug("Window %#010x has opacity %f, opacity target is %f", w->base.id,
|
log_debug("Window %#010x has opacity %f, opacity target is %f", w->base.id,
|
||||||
w->opacity, w->opacity_target);
|
w->opacity, w->opacity_target);
|
||||||
|
@ -2148,7 +2134,7 @@ void map_win_start(session_t *ps, struct managed_win *w) {
|
||||||
// the window's image will be bound
|
// the window's image will be bound
|
||||||
win_update_bounding_shape(ps, w);
|
win_update_bounding_shape(ps, w);
|
||||||
|
|
||||||
assert((w->flags & WIN_FLAGS_IMAGES_STALE) == WIN_FLAGS_IMAGES_STALE);
|
assert(win_check_flags_all(w, WIN_FLAGS_IMAGES_STALE));
|
||||||
|
|
||||||
#ifdef CONFIG_DBUS
|
#ifdef CONFIG_DBUS
|
||||||
// Send D-Bus signal
|
// Send D-Bus signal
|
||||||
|
@ -2162,6 +2148,60 @@ void map_win_start(session_t *ps, struct managed_win *w) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update target window opacity depending on the current state.
|
||||||
|
*/
|
||||||
|
void win_update_opacity_target(session_t *ps, struct managed_win *w) {
|
||||||
|
auto opacity_target_old = w->opacity_target;
|
||||||
|
w->opacity_target = win_calc_opacity_target(ps, w);
|
||||||
|
|
||||||
|
if (opacity_target_old == w->opacity_target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->state == WSTATE_MAPPED) {
|
||||||
|
// Opacity target changed while MAPPED. Transition to FADING.
|
||||||
|
assert(w->opacity == opacity_target_old);
|
||||||
|
w->opacity_target_old = opacity_target_old;
|
||||||
|
w->state = WSTATE_FADING;
|
||||||
|
log_debug("Window %#010x (%s) opacity %f, opacity target %f, set "
|
||||||
|
"old target %f",
|
||||||
|
w->base.id, w->name, w->opacity, w->opacity_target,
|
||||||
|
w->opacity_target_old);
|
||||||
|
} else if (w->state == WSTATE_MAPPING) {
|
||||||
|
// Opacity target changed while fading in.
|
||||||
|
if (w->opacity >= w->opacity_target) {
|
||||||
|
// Already reached new target opacity. Transition to
|
||||||
|
// FADING.
|
||||||
|
map_win_finish(w);
|
||||||
|
w->opacity_target_old = fmax(opacity_target_old, w->opacity);
|
||||||
|
w->state = WSTATE_FADING;
|
||||||
|
log_debug("Window %#010x (%s) opacity %f already reached "
|
||||||
|
"new opacity target %f while mapping, set old "
|
||||||
|
"target %f",
|
||||||
|
w->base.id, w->name, w->opacity, w->opacity_target,
|
||||||
|
w->opacity_target_old);
|
||||||
|
}
|
||||||
|
} else if (w->state == WSTATE_FADING) {
|
||||||
|
// Opacity target changed while FADING.
|
||||||
|
if ((w->opacity < opacity_target_old && w->opacity > w->opacity_target) ||
|
||||||
|
(w->opacity > opacity_target_old && w->opacity < w->opacity_target)) {
|
||||||
|
// Changed while fading in and will fade out or while
|
||||||
|
// fading out and will fade in.
|
||||||
|
w->opacity_target_old = opacity_target_old;
|
||||||
|
log_debug("Window %#010x (%s) opacity %f already reached "
|
||||||
|
"new opacity target %f while fading, set "
|
||||||
|
"old target %f",
|
||||||
|
w->base.id, w->name, w->opacity, w->opacity_target,
|
||||||
|
w->opacity_target_old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ps->redirected) {
|
||||||
|
CHECK(!win_skip_fading(ps, w));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a managed window from window id in window linked list of the session.
|
* Find a managed window from window id in window linked list of the session.
|
||||||
*/
|
*/
|
||||||
|
@ -2284,31 +2324,33 @@ win_is_fullscreen_xcb(xcb_connection_t *c, const struct atom *a, const xcb_windo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue an update on a window. A series of sanity checks are performed
|
/// Set flags on a window. Some sanity checks are performed
|
||||||
void win_queue_update(struct managed_win *_w, enum win_update update) {
|
void win_set_flags(struct managed_win *w, uint64_t flags) {
|
||||||
auto w = (struct managed_win_internal *)_w;
|
if (unlikely(w->state == WSTATE_DESTROYING)) {
|
||||||
assert(popcount(update) == 1);
|
log_error("Flags set on a destroyed window %#010x (%s)", w->base.id, w->name);
|
||||||
assert(update == WIN_UPDATE_MAP); // Currently the only supported update
|
|
||||||
|
|
||||||
if (unlikely(_w->state == WSTATE_DESTROYING)) {
|
|
||||||
log_error("Updates queued on a destroyed window %#010x (%s)", _w->base.id,
|
|
||||||
_w->name);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->pending_updates |= update;
|
w->flags |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process pending updates on a window. Has to be called in X critical section
|
/// Clear flags on a window. Some sanity checks are performed
|
||||||
void win_process_updates(struct session *ps, struct managed_win *_w) {
|
void win_clear_flags(struct managed_win *w, uint64_t flags) {
|
||||||
assert(ps->server_grabbed);
|
if (unlikely(w->state == WSTATE_DESTROYING)) {
|
||||||
auto w = (struct managed_win_internal *)_w;
|
log_error("Flags cleared on a destroyed window %#010x (%s)", w->base.id,
|
||||||
|
w->name);
|
||||||
if (w->pending_updates & WIN_UPDATE_MAP) {
|
return;
|
||||||
map_win_start(ps, _w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w->pending_updates = 0;
|
w->flags = w->flags & (~flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool win_check_flags_any(struct managed_win *w, uint64_t flags) {
|
||||||
|
return (w->flags & flags) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool win_check_flags_all(struct managed_win *w, uint64_t flags) {
|
||||||
|
return (w->flags & flags) == flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2364,7 +2406,6 @@ win_stack_find_next_managed(const session_t *ps, const struct list_node *i) {
|
||||||
|
|
||||||
/// Return whether this window is mapped on the X server side
|
/// Return whether this window is mapped on the X server side
|
||||||
bool win_is_mapped_in_x(const struct managed_win *w) {
|
bool win_is_mapped_in_x(const struct managed_win *w) {
|
||||||
auto iw = (const struct managed_win_internal *)w;
|
|
||||||
return w->state == WSTATE_MAPPING || w->state == WSTATE_FADING ||
|
return w->state == WSTATE_MAPPING || w->state == WSTATE_FADING ||
|
||||||
w->state == WSTATE_MAPPED || (iw->pending_updates & WIN_UPDATE_MAP);
|
w->state == WSTATE_MAPPED || (w->flags & WIN_FLAGS_MAPPED);
|
||||||
}
|
}
|
||||||
|
|
21
src/win.h
21
src/win.h
|
@ -131,7 +131,7 @@ struct managed_win {
|
||||||
/// See above about coordinate systems.
|
/// See above about coordinate systems.
|
||||||
region_t bounding_shape;
|
region_t bounding_shape;
|
||||||
/// Window flags. Definitions above.
|
/// Window flags. Definitions above.
|
||||||
int_fast16_t flags;
|
uint64_t flags;
|
||||||
/// The region of screen that will be obscured when windows above is painted,
|
/// The region of screen that will be obscured when windows above is painted,
|
||||||
/// in global coordinates.
|
/// in global coordinates.
|
||||||
/// We use this to reduce the pixels that needed to be paint when painting
|
/// We use this to reduce the pixels that needed to be paint when painting
|
||||||
|
@ -192,6 +192,8 @@ struct managed_win {
|
||||||
double opacity;
|
double opacity;
|
||||||
/// Target window opacity.
|
/// Target window opacity.
|
||||||
double opacity_target;
|
double opacity_target;
|
||||||
|
/// Previous window opacity.
|
||||||
|
double opacity_target_old;
|
||||||
/// true if window (or client window, for broken window managers
|
/// true if window (or client window, for broken window managers
|
||||||
/// not transferring client window's _NET_WM_OPACITY value) has opacity prop
|
/// not transferring client window's _NET_WM_OPACITY value) has opacity prop
|
||||||
bool has_opacity_prop;
|
bool has_opacity_prop;
|
||||||
|
@ -252,12 +254,8 @@ struct managed_win {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Process pending updates on a window. Has to be called in X critical section
|
|
||||||
void win_process_updates(struct session *ps, struct managed_win *_w);
|
|
||||||
/// Process pending images flags on a window. Has to be called in X critical section
|
/// Process pending images flags on a window. Has to be called in X critical section
|
||||||
void win_process_flags(session_t *ps, struct managed_win *w);
|
void win_process_flags(session_t *ps, struct managed_win *w);
|
||||||
/// Queue an update on a window. A series of sanity checks are performed
|
|
||||||
void win_queue_update(struct managed_win *_w, enum win_update update);
|
|
||||||
/// Bind a shadow to the window, with color `c` and shadow kernel `kernel`
|
/// Bind a shadow to the window, with color `c` and shadow kernel `kernel`
|
||||||
bool win_bind_shadow(struct backend_base *b, struct managed_win *w, struct color c,
|
bool win_bind_shadow(struct backend_base *b, struct managed_win *w, struct color c,
|
||||||
struct conv *kernel);
|
struct conv *kernel);
|
||||||
|
@ -291,6 +289,7 @@ void win_set_focused(session_t *ps, struct managed_win *w);
|
||||||
bool attr_pure win_should_fade(session_t *ps, const struct managed_win *w);
|
bool attr_pure win_should_fade(session_t *ps, const struct managed_win *w);
|
||||||
void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w);
|
void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w);
|
||||||
void win_update_prop_shadow(session_t *ps, struct managed_win *w);
|
void win_update_prop_shadow(session_t *ps, struct managed_win *w);
|
||||||
|
void win_update_opacity_target(session_t *ps, struct managed_win *w);
|
||||||
void win_on_factor_change(session_t *ps, struct managed_win *w);
|
void win_on_factor_change(session_t *ps, struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Update cache data in struct _win that depends on window size.
|
* Update cache data in struct _win that depends on window size.
|
||||||
|
@ -311,12 +310,10 @@ bool win_get_class(session_t *ps, struct managed_win *w);
|
||||||
*
|
*
|
||||||
* @param ps current session
|
* @param ps current session
|
||||||
* @param w struct _win object representing the window
|
* @param w struct _win object representing the window
|
||||||
* @param ignore_state whether window state should be ignored in opacity calculation
|
|
||||||
*
|
*
|
||||||
* @return target opacity
|
* @return target opacity
|
||||||
*/
|
*/
|
||||||
double attr_pure win_calc_opacity_target(session_t *ps, const struct managed_win *w,
|
double attr_pure win_calc_opacity_target(session_t *ps, const struct managed_win *w);
|
||||||
bool ignore_state);
|
|
||||||
bool attr_pure win_should_dim(session_t *ps, const struct managed_win *w);
|
bool attr_pure win_should_dim(session_t *ps, const struct managed_win *w);
|
||||||
void win_update_screen(session_t *, struct managed_win *);
|
void win_update_screen(session_t *, struct managed_win *);
|
||||||
/**
|
/**
|
||||||
|
@ -434,6 +431,14 @@ bool win_is_mapped_in_x(const struct managed_win *w);
|
||||||
// Find the managed window immediately below `w` in the window stack
|
// Find the managed window immediately below `w` in the window stack
|
||||||
struct managed_win *attr_pure win_stack_find_next_managed(const session_t *ps,
|
struct managed_win *attr_pure win_stack_find_next_managed(const session_t *ps,
|
||||||
const struct list_node *w);
|
const struct list_node *w);
|
||||||
|
/// Set flags on a window. Some sanity checks are performed
|
||||||
|
void win_set_flags(struct managed_win *w, uint64_t flags);
|
||||||
|
/// Clear flags on a window. Some sanity checks are performed
|
||||||
|
void win_clear_flags(struct managed_win *w, uint64_t flags);
|
||||||
|
/// Returns true if any of the flags in `flags` is set
|
||||||
|
bool win_check_flags_any(struct managed_win *w, uint64_t flags);
|
||||||
|
/// Returns true if all of the flags in `flags` are set
|
||||||
|
bool win_check_flags_all(struct managed_win *w, uint64_t flags);
|
||||||
|
|
||||||
/// Free all resources in a struct win
|
/// Free all resources in a struct win
|
||||||
void free_win_res(session_t *ps, struct managed_win *w);
|
void free_win_res(session_t *ps, struct managed_win *w);
|
||||||
|
|
|
@ -27,11 +27,6 @@ typedef enum {
|
||||||
WMODE_SOLID, // The window is opaque including the frame
|
WMODE_SOLID, // The window is opaque including the frame
|
||||||
} winmode_t;
|
} winmode_t;
|
||||||
|
|
||||||
/// Pending window updates
|
|
||||||
enum win_update {
|
|
||||||
WIN_UPDATE_MAP = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Transition table:
|
/// Transition table:
|
||||||
/// (DESTROYED is when the win struct is destroyed and freed)
|
/// (DESTROYED is when the win struct is destroyed and freed)
|
||||||
/// ('o' means in all other cases)
|
/// ('o' means in all other cases)
|
||||||
|
@ -45,8 +40,8 @@ enum win_update {
|
||||||
/// | DESTROYING | - | o | - | - | - | - | Fading |
|
/// | DESTROYING | - | o | - | - | - | - | Fading |
|
||||||
/// | | | | | | | |finished |
|
/// | | | | | | | |finished |
|
||||||
/// +-------------+---------+----------+-------+-------+--------+--------+---------+
|
/// +-------------+---------+----------+-------+-------+--------+--------+---------+
|
||||||
/// | MAPPING | Window | Window | o | - | - | Fading | - |
|
/// | MAPPING | Window | Window | o |Opacity| - | Fading | - |
|
||||||
/// | |unmapped |destroyed | | | |finished| |
|
/// | |unmapped |destroyed | |change | |finished| |
|
||||||
/// +-------------+---------+----------+-------+-------+--------+--------+---------+
|
/// +-------------+---------+----------+-------+-------+--------+--------+---------+
|
||||||
/// | FADING | Window | Window | - | o | - | Fading | - |
|
/// | FADING | Window | Window | - | o | - | Fading | - |
|
||||||
/// | |unmapped |destroyed | | | |finished| |
|
/// | |unmapped |destroyed | | | |finished| |
|
||||||
|
@ -86,9 +81,11 @@ enum win_flags {
|
||||||
WIN_FLAGS_SHADOW_STALE = 8,
|
WIN_FLAGS_SHADOW_STALE = 8,
|
||||||
/// shadow has not been generated
|
/// shadow has not been generated
|
||||||
WIN_FLAGS_SHADOW_NONE = 16,
|
WIN_FLAGS_SHADOW_NONE = 16,
|
||||||
|
/// the window is mapped by X, we need to call map_win_start for it
|
||||||
|
WIN_FLAGS_MAPPED = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int_fast16_t WIN_FLAGS_IMAGES_STALE =
|
static const uint64_t WIN_FLAGS_IMAGES_STALE =
|
||||||
WIN_FLAGS_PIXMAP_STALE | WIN_FLAGS_SHADOW_STALE;
|
WIN_FLAGS_PIXMAP_STALE | WIN_FLAGS_SHADOW_STALE;
|
||||||
|
|
||||||
#define WIN_FLAGS_IMAGES_NONE (WIN_FLAGS_PIXMAP_NONE | WIN_FLAGS_SHADOW_NONE)
|
#define WIN_FLAGS_IMAGES_NONE (WIN_FLAGS_PIXMAP_NONE | WIN_FLAGS_SHADOW_NONE)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fading = true
|
fading = true
|
||||||
fade-in-step = 1
|
fade-in-step = 0.01
|
||||||
fade-out-step = 0.01
|
fade-out-step = 0.01
|
||||||
inactive-opacity = 0
|
inactive-opacity = 0
|
||||||
blur-background = true
|
blur-background = true
|
||||||
|
|
|
@ -10,3 +10,5 @@ cd $(dirname $0)
|
||||||
./run_one_test.sh $exe configs/issue239_3.conf testcases/issue239_3.py
|
./run_one_test.sh $exe configs/issue239_3.conf testcases/issue239_3.py
|
||||||
./run_one_test.sh $exe configs/issue239_3.conf testcases/issue239_3_norefresh.py
|
./run_one_test.sh $exe configs/issue239_3.conf testcases/issue239_3_norefresh.py
|
||||||
./run_one_test.sh $exe configs/issue314.conf testcases/issue314.py
|
./run_one_test.sh $exe configs/issue314.conf testcases/issue314.py
|
||||||
|
./run_one_test.sh $exe configs/issue314.conf testcases/issue314_2.py
|
||||||
|
./run_one_test.sh $exe configs/issue314.conf testcases/issue314_3.py
|
||||||
|
|
|
@ -12,11 +12,11 @@ visual = setup.roots[0].root_visual
|
||||||
depth = setup.roots[0].root_depth
|
depth = setup.roots[0].root_depth
|
||||||
x = xproto.xprotoExtension(conn)
|
x = xproto.xprotoExtension(conn)
|
||||||
|
|
||||||
# issue 239 is caused by a window gaining a shadow during its fade-out transition
|
# issue 314 is caused by changing a windows target opacity during its fade-in/-out transition
|
||||||
wid1 = conn.generate_id()
|
wid1 = conn.generate_id()
|
||||||
print("Window 1: ", hex(wid1))
|
print("Window 1: ", hex(wid1))
|
||||||
wid2 = conn.generate_id()
|
wid2 = conn.generate_id()
|
||||||
print("Window 1: ", hex(wid2))
|
print("Window 2: ", hex(wid2))
|
||||||
|
|
||||||
# Create windows
|
# Create windows
|
||||||
conn.core.CreateWindowChecked(depth, wid1, root, 0, 0, 100, 100, 0, xproto.WindowClass.InputOutput, visual, 0, []).check()
|
conn.core.CreateWindowChecked(depth, wid1, root, 0, 0, 100, 100, 0, xproto.WindowClass.InputOutput, visual, 0, []).check()
|
||||||
|
@ -26,20 +26,19 @@ conn.core.CreateWindowChecked(depth, wid2, root, 0, 0, 100, 100, 0, xproto.Windo
|
||||||
set_window_name(conn, wid1, "Test window 1")
|
set_window_name(conn, wid1, "Test window 1")
|
||||||
set_window_name(conn, wid2, "Test window 2")
|
set_window_name(conn, wid2, "Test window 2")
|
||||||
|
|
||||||
print("mapping 1")
|
# Check updating opacity while UNMAPPING/DESTROYING windows
|
||||||
|
print("Mapping 1")
|
||||||
conn.core.MapWindowChecked(wid1).check()
|
conn.core.MapWindowChecked(wid1).check()
|
||||||
print("mapping 2")
|
print("Mapping 2")
|
||||||
conn.core.MapWindowChecked(wid2).check()
|
conn.core.MapWindowChecked(wid2).check()
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
x.SetInputFocusChecked(0, wid1, xproto.Time.CurrentTime).check()
|
x.SetInputFocusChecked(0, wid1, xproto.Time.CurrentTime).check()
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
# Destroy the windows
|
# Destroy the windows
|
||||||
|
print("Destroy 1 while fading out")
|
||||||
conn.core.DestroyWindowChecked(wid1).check()
|
conn.core.DestroyWindowChecked(wid1).check()
|
||||||
|
|
||||||
x.SetInputFocusChecked(0, wid2, xproto.Time.CurrentTime).check()
|
x.SetInputFocusChecked(0, wid2, xproto.Time.CurrentTime).check()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
conn.core.DestroyWindowChecked(wid2).check()
|
conn.core.DestroyWindowChecked(wid2).check()
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import xcffib.xproto as xproto
|
||||||
|
import xcffib
|
||||||
|
import time
|
||||||
|
from common import set_window_name, trigger_root_configure
|
||||||
|
|
||||||
|
conn = xcffib.connect()
|
||||||
|
setup = conn.get_setup()
|
||||||
|
root = setup.roots[0].root
|
||||||
|
visual = setup.roots[0].root_visual
|
||||||
|
depth = setup.roots[0].root_depth
|
||||||
|
x = xproto.xprotoExtension(conn)
|
||||||
|
|
||||||
|
opacity_80 = [int(0xffffffff * 0.8), ]
|
||||||
|
opacity_single = [int(0xffffffff * 0.002), ]
|
||||||
|
|
||||||
|
# issue 314 is caused by changing a windows target opacity during its fade-in/-out transition
|
||||||
|
wid1 = conn.generate_id()
|
||||||
|
print("Window 1: ", hex(wid1))
|
||||||
|
|
||||||
|
atom = "_NET_WM_WINDOW_OPACITY"
|
||||||
|
opacity_atom = conn.core.InternAtom(False, len(atom), atom).reply().atom
|
||||||
|
|
||||||
|
# Create windows
|
||||||
|
conn.core.CreateWindowChecked(depth, wid1, root, 0, 0, 100, 100, 0, xproto.WindowClass.InputOutput, visual, 0, []).check()
|
||||||
|
|
||||||
|
# Set Window names
|
||||||
|
set_window_name(conn, wid1, "Test window 1")
|
||||||
|
|
||||||
|
# Check updating opacity while MAPPING windows
|
||||||
|
print("Mapping window")
|
||||||
|
conn.core.MapWindowChecked(wid1).check()
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
print("Update opacity while fading in")
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_80).check()
|
||||||
|
time.sleep(0.2)
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_single).check()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
conn.core.DeletePropertyChecked(wid1, opacity_atom).check()
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# Destroy the windows
|
||||||
|
conn.core.DestroyWindowChecked(wid1).check()
|
|
@ -0,0 +1,63 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import xcffib.xproto as xproto
|
||||||
|
import xcffib
|
||||||
|
import time
|
||||||
|
from common import set_window_name, trigger_root_configure
|
||||||
|
|
||||||
|
conn = xcffib.connect()
|
||||||
|
setup = conn.get_setup()
|
||||||
|
root = setup.roots[0].root
|
||||||
|
visual = setup.roots[0].root_visual
|
||||||
|
depth = setup.roots[0].root_depth
|
||||||
|
x = xproto.xprotoExtension(conn)
|
||||||
|
|
||||||
|
opacity_100 = [0xffffffff, ]
|
||||||
|
opacity_80 = [int(0xffffffff * 0.8), ]
|
||||||
|
opacity_single = [int(0xffffffff * 0.002), ]
|
||||||
|
opacity_0 = [0, ]
|
||||||
|
|
||||||
|
# issue 314 is caused by changing a windows target opacity during its fade-in/-out transition
|
||||||
|
wid1 = conn.generate_id()
|
||||||
|
print("Window 1: ", hex(wid1))
|
||||||
|
|
||||||
|
atom = "_NET_WM_WINDOW_OPACITY"
|
||||||
|
opacity_atom = conn.core.InternAtom(False, len(atom), atom).reply().atom
|
||||||
|
|
||||||
|
# Create windows
|
||||||
|
conn.core.CreateWindowChecked(depth, wid1, root, 0, 0, 100, 100, 0, xproto.WindowClass.InputOutput, visual, 0, []).check()
|
||||||
|
|
||||||
|
# Set Window names
|
||||||
|
set_window_name(conn, wid1, "Test window 1")
|
||||||
|
|
||||||
|
# Check updating opacity while FADING windows
|
||||||
|
print("Mapping window")
|
||||||
|
conn.core.MapWindowChecked(wid1).check()
|
||||||
|
time.sleep(1.2)
|
||||||
|
|
||||||
|
print("Update opacity while fading out")
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_single).check()
|
||||||
|
time.sleep(0.2)
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_0).check()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("Change from fading in to fading out")
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_80).check()
|
||||||
|
time.sleep(0.5)
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_0).check()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("Update opacity while fading in")
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_80).check()
|
||||||
|
time.sleep(0.2)
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_100).check()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("Change from fading out to fading in")
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_0).check()
|
||||||
|
time.sleep(0.5)
|
||||||
|
conn.core.ChangePropertyChecked(xproto.PropMode.Replace, wid1, opacity_atom, xproto.Atom.CARDINAL, 32, 1, opacity_80).check()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Destroy the windows
|
||||||
|
conn.core.DestroyWindowChecked(wid1).check()
|
Loading…
Reference in New Issue