2 Commits

Author SHA1 Message Date
Arda Atci
e9834a5e35 fix on desktop switch
Some checks failed
coding-style / check (push) Has been cancelled
2023-04-25 03:47:31 +03:00
Arda Atci
fb99c9e472 added support for other wm 2023-04-22 13:46:16 +03:00
6 changed files with 108 additions and 64 deletions

View File

@@ -23,7 +23,8 @@
WM_CLIENT_MACHINE, \ WM_CLIENT_MACHINE, \
_NET_ACTIVE_WINDOW, \ _NET_ACTIVE_WINDOW, \
_COMPTON_SHADOW, \ _COMPTON_SHADOW, \
_NET_WM_WINDOW_TYPE _NET_WM_DESKTOP, \
_NET_CURRENT_DESKTOP
#define ATOM_LIST2 \ #define ATOM_LIST2 \
_NET_WM_WINDOW_TYPE_DESKTOP, \ _NET_WM_WINDOW_TYPE_DESKTOP, \
@@ -43,6 +44,7 @@
_NET_WM_STATE, \ _NET_WM_STATE, \
_NET_WM_STATE_FULLSCREEN, \ _NET_WM_STATE_FULLSCREEN, \
_NET_WM_BYPASS_COMPOSITOR, \ _NET_WM_BYPASS_COMPOSITOR, \
_NET_WM_WINDOW_TYPE, \
UTF8_STRING, \ UTF8_STRING, \
C_STRING C_STRING
// clang-format on // clang-format on

View File

@@ -206,9 +206,6 @@ typedef struct session {
/// Width of root window. /// Width of root window.
int root_width; int root_width;
// Damage of root window. // Damage of root window.
// Damage root_damage;
int selmon_center_x;
int selmon_center_y;
/// X Composite overlay window. /// X Composite overlay window.
xcb_window_t overlay; xcb_window_t overlay;
/// The target window for debug mode /// The target window for debug mode
@@ -294,6 +291,8 @@ typedef struct session {
int size_expose; int size_expose;
/// Index of the next free slot in <code>expose_rects</code>. /// Index of the next free slot in <code>expose_rects</code>.
int n_expose; int n_expose;
/// Current desktop of display
uint32_t cur_desktop;
// === Window related === // === Window related ===
/// A hash table of all windows. /// A hash table of all windows.

View File

@@ -453,6 +453,27 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
if (ps->root == ev->window) { if (ps->root == ev->window) {
if (ev->atom == ps->atoms->a_NET_CURRENT_DESKTOP) {
auto prop = x_get_prop(ps->c, ps->root, ps->atoms->a_NET_CURRENT_DESKTOP,
1L, XCB_ATOM_CARDINAL, 32);
if (prop.nitems) {
if (ps->cur_desktop != *prop.c32) {
win_stack_foreach_managed_safe(w, &ps->window_stack) {
if (w->a.override_redirect) {
continue;
}
if (w->cur_desktop & *prop.c32) {
w->dwm_mask = ANIM_NEXT_TAG;
} else if (w->cur_desktop & ps->cur_desktop) {
w->dwm_mask = ANIM_PREV_TAG;
}
}
ps->cur_desktop = *prop.c32;
}
}
}
if (ps->o.use_ewmh_active_win && ps->atoms->a_NET_ACTIVE_WINDOW == ev->atom) { if (ps->o.use_ewmh_active_win && ps->atoms->a_NET_ACTIVE_WINDOW == ev->atom) {
// to update focus // to update focus
ps->pending_updates = true; ps->pending_updates = true;

View File

@@ -1882,6 +1882,8 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
.white_picture = XCB_NONE, .white_picture = XCB_NONE,
.shadow_context = NULL, .shadow_context = NULL,
.cur_desktop = 0,
#ifdef CONFIG_VSYNC_DRM #ifdef CONFIG_VSYNC_DRM
.drm_fd = -1, .drm_fd = -1,
#endif #endif

123
src/win.c
View File

@@ -445,6 +445,10 @@ static void win_update_properties(session_t *ps, struct managed_win *w) {
} }
} }
if (win_fetch_and_unset_property_stale(w, ps->atoms->a_NET_WM_DESKTOP)) {
win_update_prop_desktop(ps, w);
}
if (win_fetch_and_unset_property_stale(w, ps->atoms->aWM_CLASS)) { if (win_fetch_and_unset_property_stale(w, ps->atoms->aWM_CLASS)) {
if (win_update_class(ps, w)) { if (win_update_class(ps, w)) {
win_set_flags(w, WIN_FLAGS_FACTOR_CHANGED); win_set_flags(w, WIN_FLAGS_FACTOR_CHANGED);
@@ -686,10 +690,10 @@ void win_process_update_flags(session_t *ps, struct managed_win *w) {
// Determine if a window should animate // Determine if a window should animate
if (win_should_animate(ps, w)) { if (win_should_animate(ps, w)) {
win_update_bounding_shape(ps, w); win_update_bounding_shape(ps, w);
if (w->pending_g.y < 0 && w->g.y > 0 && abs(w->pending_g.y - w->g.y) >= w->pending_g.height) // if (w->pending_g.y < 0 && w->g.y > 0 && abs(w->pending_g.y - w->g.y) >= w->pending_g.height)
w->dwm_mask = ANIM_PREV_TAG; // w->dwm_mask = ANIM_PREV_TAG;
else if (w->pending_g.y > 0 && w->g.y < 0 && abs(w->pending_g.y - w->g.y) >= w->pending_g.height) // else if (w->pending_g.y > 0 && w->g.y < 0 && abs(w->pending_g.y - w->g.y) >= w->pending_g.height)
w->dwm_mask = ANIM_NEXT_TAG; // w->dwm_mask = ANIM_NEXT_TAG;
if (!was_visible || w->dwm_mask) { if (!was_visible || w->dwm_mask) {
@@ -707,7 +711,6 @@ void win_process_update_flags(session_t *ps, struct managed_win *w) {
w->g.width = (uint16_t)round(w->animation_w); w->g.width = (uint16_t)round(w->animation_w);
w->g.height = (uint16_t)round(w->animation_h); w->g.height = (uint16_t)round(w->animation_h);
} }
} else { } else {
w->animation_is_tag = ANIM_IN_TAG; w->animation_is_tag = ANIM_IN_TAG;
w->animation_dest_center_x = w->animation_dest_center_x =
@@ -718,37 +721,37 @@ void win_process_update_flags(session_t *ps, struct managed_win *w) {
w->animation_dest_h = w->pending_g.height; w->animation_dest_h = w->pending_g.height;
} }
CLEAR_MASK(w->dwm_mask) CLEAR_MASK(w->dwm_mask)
w->g.border_width = w->pending_g.border_width; w->g.border_width = w->pending_g.border_width;
double x_dist = w->animation_dest_center_x - w->animation_center_x; double x_dist = w->animation_dest_center_x - w->animation_center_x;
double y_dist = w->animation_dest_center_y - w->animation_center_y; double y_dist = w->animation_dest_center_y - w->animation_center_y;
double w_dist = w->animation_dest_w - w->animation_w; double w_dist = w->animation_dest_w - w->animation_w;
double h_dist = w->animation_dest_h - w->animation_h; double h_dist = w->animation_dest_h - w->animation_h;
w->animation_inv_og_distance = w->animation_inv_og_distance =
1.0 / sqrt(x_dist * x_dist + y_dist * y_dist + 1.0 / sqrt(x_dist * x_dist + y_dist * y_dist +
w_dist * w_dist + h_dist * h_dist); w_dist * w_dist + h_dist * h_dist);
if (isinf(w->animation_inv_og_distance)) if (isinf(w->animation_inv_og_distance))
w->animation_inv_og_distance = 0; w->animation_inv_og_distance = 0;
// We only grab images if w->reg_ignore_valid is true as // We only grab images if w->reg_ignore_valid is true as
// there's an ev_shape_notify() event fired quickly on new windows // there's an ev_shape_notify() event fired quickly on new windows
// for e.g. in case of Firefox main menu and ev_shape_notify() // for e.g. in case of Firefox main menu and ev_shape_notify()
// sets the win_set_flags(w, WIN_FLAGS_SIZE_STALE); which // sets the win_set_flags(w, WIN_FLAGS_SIZE_STALE); which
// brakes the new image captured and because this same event // brakes the new image captured and because this same event
// also sets w->reg_ignore_valid = false; too we check for it // also sets w->reg_ignore_valid = false; too we check for it
if (w->reg_ignore_valid) { if (w->reg_ignore_valid) {
if (w->old_win_image) { if (w->old_win_image) {
ps->backend_data->ops->release_image(ps->backend_data, ps->backend_data->ops->release_image(ps->backend_data,
w->old_win_image); w->old_win_image);
w->old_win_image = NULL; w->old_win_image = NULL;
} }
// We only grab // We only grab
if (w->win_image) { if (w->win_image) {
w->old_win_image = ps->backend_data->ops->clone_image( w->old_win_image = ps->backend_data->ops->clone_image(
ps->backend_data, w->win_image, &w->bounding_shape); ps->backend_data, w->win_image, &w->bounding_shape);
} }
} }
w->animation_progress = 0.0; w->animation_progress = 0.0;
@@ -1170,6 +1173,17 @@ void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w) {
free_winprop(&prop); free_winprop(&prop);
} }
void win_update_prop_desktop(session_t *ps, struct managed_win *w) {
winprop_t prop = x_get_prop(ps->c, w->base.id, ps->atoms->a_NET_WM_DESKTOP, 1,
XCB_ATOM_CARDINAL, 32);
if (!prop.nitems) {
w->cur_desktop = w->cur_desktop;
} else {
w->cur_desktop = *prop.c32;
}
free_winprop(&prop);
}
static void win_set_shadow(session_t *ps, struct managed_win *w, bool shadow_new) { static void win_set_shadow(session_t *ps, struct managed_win *w, bool shadow_new) {
if (w->shadow == shadow_new) { if (w->shadow == shadow_new) {
return; return;
@@ -1994,6 +2008,7 @@ struct win *fill_win(session_t *ps, struct win *w) {
ps->atoms->a_NET_WM_NAME, ps->atoms->aWM_CLASS, ps->atoms->a_NET_WM_NAME, ps->atoms->aWM_CLASS,
ps->atoms->aWM_WINDOW_ROLE, ps->atoms->a_COMPTON_SHADOW, ps->atoms->aWM_WINDOW_ROLE, ps->atoms->a_COMPTON_SHADOW,
ps->atoms->aWM_CLIENT_LEADER, ps->atoms->aWM_TRANSIENT_FOR, ps->atoms->aWM_CLIENT_LEADER, ps->atoms->aWM_TRANSIENT_FOR,
ps->atoms->a_NET_WM_DESKTOP
}; };
win_set_properties_stale(new, init_stale_props, ARR_SIZE(init_stale_props)); win_set_properties_stale(new, init_stale_props, ARR_SIZE(init_stale_props));
@@ -2686,29 +2701,31 @@ void unmap_win_start(session_t *ps, struct managed_win *w) {
w->opacity_target_old = fmax(w->opacity_target, w->opacity_target_old); w->opacity_target_old = fmax(w->opacity_target, w->opacity_target_old);
w->opacity_target = win_calc_opacity_target(ps, w); w->opacity_target = win_calc_opacity_target(ps, w);
if (ps->o.animations && ps->o.animation_for_unmap_window != OPEN_WINDOW_ANIMATION_NONE && ps->o.wintype_option[w->window_type].animation) { if (ps->o.animations &&
w->dwm_mask = ANIM_UNMAP; ps->o.animation_for_unmap_window != OPEN_WINDOW_ANIMATION_NONE &&
init_animation(ps, w); ps->o.wintype_option[w->window_type].animation) {
w->dwm_mask = ANIM_UNMAP;
init_animation(ps, w);
double x_dist = w->animation_dest_center_x - w->animation_center_x; double x_dist = w->animation_dest_center_x - w->animation_center_x;
double y_dist = w->animation_dest_center_y - w->animation_center_y; double y_dist = w->animation_dest_center_y - w->animation_center_y;
double w_dist = w->animation_dest_w - w->animation_w; double w_dist = w->animation_dest_w - w->animation_w;
double h_dist = w->animation_dest_h - w->animation_h; double h_dist = w->animation_dest_h - w->animation_h;
w->animation_inv_og_distance = w->animation_inv_og_distance =
1.0 / sqrt(x_dist * x_dist + y_dist * y_dist + 1.0 / sqrt(x_dist * x_dist + y_dist * y_dist +
w_dist * w_dist + h_dist * h_dist); w_dist * w_dist + h_dist * h_dist);
if (isinf(w->animation_inv_og_distance)) if (isinf(w->animation_inv_og_distance))
w->animation_inv_og_distance = 0; w->animation_inv_og_distance = 0;
w->animation_progress = 0.0; w->animation_progress = 0.0;
if (w->old_win_image) { if (w->old_win_image) {
ps->backend_data->ops->release_image(ps->backend_data, ps->backend_data->ops->release_image(ps->backend_data,
w->old_win_image); w->old_win_image);
w->old_win_image = NULL; w->old_win_image = NULL;
} }
} }
#ifdef CONFIG_DBUS #ifdef CONFIG_DBUS
// Send D-Bus signal // Send D-Bus signal
@@ -2771,7 +2788,7 @@ void win_update_monitor(int nmons, region_t *mons, struct managed_win *mw) {
auto e = pixman_region32_extents(&mons[i]); auto e = pixman_region32_extents(&mons[i]);
// if (e->x1 <= mw->g.x && e->y1 <= mw->g.y && // if (e->x1 <= mw->g.x && e->y1 <= mw->g.y &&
// e->x2 >= mw->g.x + mw->widthb && e->y2 >= mw->g.y + mw->heightb) { // e->x2 >= mw->g.x + mw->widthb && e->y2 >= mw->g.y + mw->heightb) {
if (e->x1 <= mw->g.x && e->x2 >= mw->g.x + mw->widthb) { if (e->x1 <= mw->pending_g.x && e->x2 >= mw->pending_g.x + mw->widthb) {
mw->randr_monitor = i; mw->randr_monitor = i;
log_debug("Window %#010x (%s), %dx%d+%dx%d, is entirely on the " log_debug("Window %#010x (%s), %dx%d+%dx%d, is entirely on the "
"monitor %d (%dx%d+%dx%d)", "monitor %d (%dx%d+%dx%d)",

View File

@@ -125,6 +125,7 @@ struct managed_win {
struct managed_win *prev_trans; struct managed_win *prev_trans;
/// Number of windows above this window /// Number of windows above this window
int stacking_rank; int stacking_rank;
uint32_t cur_desktop;
// TODO(yshui) rethink reg_ignore // TODO(yshui) rethink reg_ignore
// Core members // Core members
@@ -170,8 +171,8 @@ struct managed_win {
/// opacity state, window geometry, window mapped/unmapped state, /// opacity state, window geometry, window mapped/unmapped state,
/// window mode of the windows above. DOES NOT INCLUDE the body of THIS WINDOW. /// window mode of the windows above. DOES NOT INCLUDE the body of THIS WINDOW.
/// NULL means reg_ignore has not been calculated for this window. /// NULL means reg_ignore has not been calculated for this window.
/// 1 = tag prev , 2 = tag next, 4 = unmap /// 1 = tag prev , 2 = tag next, 4 = unmap
uint32_t dwm_mask; uint32_t dwm_mask;
rc_region_t *reg_ignore; rc_region_t *reg_ignore;
/// Whether the reg_ignore of all windows beneath this window are valid /// Whether the reg_ignore of all windows beneath this window are valid
bool reg_ignore_valid; bool reg_ignore_valid;
@@ -202,11 +203,11 @@ struct managed_win {
/// Inverse of the window distance at the start of animation, for /// Inverse of the window distance at the start of animation, for
/// tracking animation progress /// tracking animation progress
double animation_inv_og_distance; double animation_inv_og_distance;
/// Animation info if it is a tag change & check if its changing window sizes /// Animation info if it is a tag change & check if its changing window sizes
/// 0: no tag change /// 0: no tag change
/// 1: normal tag change animation /// 1: normal tag change animation
/// 2: tag change animation that effects window size /// 2: tag change animation that effects window size
uint16_t animation_is_tag; uint16_t animation_is_tag;
// Client window related members // Client window related members
/// ID of the top-level client window of the window. /// ID of the top-level client window of the window.
@@ -565,3 +566,5 @@ static inline bool attr_pure attr_unused win_has_frame(const struct managed_win
return w->g.border_width || w->frame_extents.top || w->frame_extents.left || return w->g.border_width || w->frame_extents.top || w->frame_extents.left ||
w->frame_extents.right || w->frame_extents.bottom; w->frame_extents.right || w->frame_extents.bottom;
} }
void win_update_prop_desktop(session_t *ps, struct managed_win *w);