win: split struct win
Currently compton handles window creation event by immediately query all the information it needs and create a window struct with that information. However, this is prone to race conditions. In the future, we want to react to window creation event by creating a placeholder in the window stack, and only query window information in a critical section where the X server is grabbed by us. This commit split struct win into two struct, one as placeholder, the other for holding actual window information. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
27603343a1
commit
bd4c242015
|
@ -50,7 +50,7 @@ region_t get_damage(session_t *ps, bool all_damage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// paint all windows
|
/// paint all windows
|
||||||
void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||||
// All painting will be limited to the damage, if _some_ of
|
// All painting will be limited to the damage, if _some_ of
|
||||||
// the paints bleed out of the damage region, it will destroy
|
// the paints bleed out of the damage region, it will destroy
|
||||||
// part of the image we want to reuse
|
// part of the image we want to reuse
|
||||||
|
@ -98,7 +98,7 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
||||||
// on top of that window. This is used to reduce the number of pixels painted.
|
// on top of that window. This is used to reduce the number of pixels painted.
|
||||||
//
|
//
|
||||||
// Whether this is beneficial is to be determined XXX
|
// Whether this is beneficial is to be determined XXX
|
||||||
for (win *w = t; w; w = w->prev_trans) {
|
for (auto w = t; w; w = w->prev_trans) {
|
||||||
pixman_region32_subtract(®_visible, &ps->screen_reg, w->reg_ignore);
|
pixman_region32_subtract(®_visible, &ps->screen_reg, w->reg_ignore);
|
||||||
assert(!(w->flags & WIN_FLAGS_IMAGE_ERROR));
|
assert(!(w->flags & WIN_FLAGS_IMAGE_ERROR));
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "x.h"
|
#include "x.h"
|
||||||
|
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
typedef struct win win;
|
struct managed_win;
|
||||||
|
|
||||||
struct backend_operations;
|
struct backend_operations;
|
||||||
|
|
||||||
|
@ -129,8 +129,7 @@ struct backend_operations {
|
||||||
// want to break that assumption as for now. We need to reconsider this.
|
// want to break that assumption as for now. We need to reconsider this.
|
||||||
|
|
||||||
/// Free resources associated with an image data structure
|
/// Free resources associated with an image data structure
|
||||||
void (*release_image)(backend_t *backend_data, void *img_data)
|
void (*release_image)(backend_t *backend_data, void *img_data) attr_nonnull(1, 2);
|
||||||
attr_nonnull(1, 2);
|
|
||||||
|
|
||||||
// =========== Query ===========
|
// =========== Query ===========
|
||||||
|
|
||||||
|
@ -183,8 +182,7 @@ typedef backend_t *(*backend_init_fn)(session_t *ps) attr_nonnull(1);
|
||||||
|
|
||||||
extern struct backend_operations *backend_list[];
|
extern struct backend_operations *backend_list[];
|
||||||
|
|
||||||
bool default_is_win_transparent(void *, win *, void *);
|
void paint_all_new(session_t *ps, struct managed_win *const t, bool ignore_damage)
|
||||||
bool default_is_frame_transparent(void *, win *, void *);
|
attr_nonnull(1);
|
||||||
void paint_all_new(session_t *ps, win *const t, bool ignore_damage) attr_nonnull(1);
|
|
||||||
|
|
||||||
// vim: set noet sw=8 ts=8 :
|
// vim: set noet sw=8 ts=8 :
|
||||||
|
|
|
@ -279,11 +279,3 @@ default_backend_render_shadow(backend_t *backend_data, int width, int height,
|
||||||
xcb_render_free_picture(backend_data->c, pict);
|
xcb_render_free_picture(backend_data->c, pict);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool default_is_win_transparent(void *backend_data, win *w, void *win_data) {
|
|
||||||
return w->mode != WMODE_SOLID;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool default_is_frame_transparent(void *backend_data, win *w, void *win_data) {
|
|
||||||
return w->frame_opacity != 1;
|
|
||||||
}
|
|
||||||
|
|
12
src/c2.c
12
src/c2.c
|
@ -310,7 +310,7 @@ static void attr_unused c2_dump(c2_ptr_t p);
|
||||||
|
|
||||||
static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf);
|
static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf);
|
||||||
|
|
||||||
static bool c2_match_once(session_t *ps, const win *w, const c2_ptr_t cond);
|
static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a condition string.
|
* Parse a condition string.
|
||||||
|
@ -1272,11 +1272,11 @@ static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf) {
|
||||||
*
|
*
|
||||||
* For internal use.
|
* For internal use.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void c2_match_once_leaf(session_t *ps, const struct managed_win *w,
|
||||||
c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres, bool *perr) {
|
const c2_l_t *pleaf, bool *pres, bool *perr) {
|
||||||
assert(pleaf);
|
assert(pleaf);
|
||||||
|
|
||||||
const xcb_window_t wid = (pleaf->tgt_onframe ? w->client_win : w->id);
|
const xcb_window_t wid = (pleaf->tgt_onframe ? w->client_win : w->base.id);
|
||||||
|
|
||||||
// Return if wid is missing
|
// Return if wid is missing
|
||||||
if (pleaf->predef == C2_L_PUNDEFINED && !wid) {
|
if (pleaf->predef == C2_L_PUNDEFINED && !wid) {
|
||||||
|
@ -1468,7 +1468,7 @@ c2_match_once_leaf(session_t *ps, const win *w, const c2_l_t *pleaf, bool *pres,
|
||||||
*
|
*
|
||||||
* @return true if matched, false otherwise.
|
* @return true if matched, false otherwise.
|
||||||
*/
|
*/
|
||||||
static bool c2_match_once(session_t *ps, const win *w, const c2_ptr_t cond) {
|
static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
bool error = true;
|
bool error = true;
|
||||||
|
|
||||||
|
@ -1542,7 +1542,7 @@ static bool c2_match_once(session_t *ps, const win *w, const c2_ptr_t cond) {
|
||||||
* @param pdata a place to return the data
|
* @param pdata a place to return the data
|
||||||
* @return true if matched, false otherwise.
|
* @return true if matched, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool c2_match(session_t *ps, const win *w, const c2_lptr_t *condlst, void **pdata) {
|
bool c2_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst, void **pdata) {
|
||||||
// Then go through the whole linked list
|
// Then go through the whole linked list
|
||||||
for (; condlst; condlst = condlst->next) {
|
for (; condlst; condlst = condlst->next) {
|
||||||
if (c2_match_once(ps, w, condlst->ptr)) {
|
if (c2_match_once(ps, w, condlst->ptr)) {
|
||||||
|
|
4
src/c2.h
4
src/c2.h
|
@ -15,12 +15,12 @@
|
||||||
|
|
||||||
typedef struct _c2_lptr c2_lptr_t;
|
typedef struct _c2_lptr c2_lptr_t;
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
typedef struct win win;
|
struct managed_win;
|
||||||
|
|
||||||
c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
|
c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
|
||||||
|
|
||||||
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp);
|
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp);
|
||||||
|
|
||||||
bool c2_match(session_t *ps, const win *w, const c2_lptr_t *condlst, void **pdata);
|
bool c2_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst, void **pdata);
|
||||||
|
|
||||||
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list);
|
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list);
|
||||||
|
|
52
src/common.h
52
src/common.h
|
@ -391,7 +391,7 @@ typedef struct session {
|
||||||
|
|
||||||
// === Window related ===
|
// === Window related ===
|
||||||
/// A hash table of all windows.
|
/// A hash table of all windows.
|
||||||
win *windows;
|
struct win *windows;
|
||||||
/// Windows in their stacking order
|
/// Windows in their stacking order
|
||||||
struct list_node window_stack;
|
struct list_node window_stack;
|
||||||
/// Pointer to <code>win</code> of current active window. Used by
|
/// Pointer to <code>win</code> of current active window. Used by
|
||||||
|
@ -399,7 +399,7 @@ typedef struct session {
|
||||||
/// it's more reliable to store the window ID directly here, just in
|
/// it's more reliable to store the window ID directly here, just in
|
||||||
/// case the WM does something extraordinary, but caching the pointer
|
/// case the WM does something extraordinary, but caching the pointer
|
||||||
/// means another layer of complexity.
|
/// means another layer of complexity.
|
||||||
win *active_win;
|
struct managed_win *active_win;
|
||||||
/// Window ID of leader window of currently active window. Used for
|
/// Window ID of leader window of currently active window. Used for
|
||||||
/// subsidiary window detection.
|
/// subsidiary window detection.
|
||||||
xcb_window_t active_leader;
|
xcb_window_t active_leader;
|
||||||
|
@ -742,32 +742,20 @@ static inline bool bkend_use_glx(session_t *ps) {
|
||||||
return BKEND_GLX == ps->o.backend || BKEND_XR_GLX_HYBRID == ps->o.backend;
|
return BKEND_GLX == ps->o.backend || BKEND_XR_GLX_HYBRID == ps->o.backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a window is really focused.
|
|
||||||
*/
|
|
||||||
static inline bool win_is_focused_real(session_t *ps, const win *w) {
|
|
||||||
return w->a.map_state == XCB_MAP_STATE_VIEWABLE && ps->active_win == w;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find out the currently focused window.
|
* Find out the currently focused window.
|
||||||
*
|
*
|
||||||
* @return struct win object of the found window, NULL if not found
|
* @return struct win object of the found window, NULL if not found
|
||||||
*/
|
*/
|
||||||
static inline win *find_focused(session_t *ps) {
|
static inline struct managed_win *find_focused(session_t *ps) {
|
||||||
if (!ps->o.track_focus)
|
if (!ps->o.track_focus) {
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (ps->active_win && win_is_focused_real(ps, ps->active_win))
|
|
||||||
return ps->active_win;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (ps->active_win && win_is_focused_real(ps, ps->active_win)) {
|
||||||
* Check if a rectangle includes the whole screen.
|
return ps->active_win;
|
||||||
*/
|
}
|
||||||
static inline bool rect_is_fullscreen(session_t *ps, int x, int y, int wid, int hei) {
|
return NULL;
|
||||||
return (x <= 0 && y <= 0 && (x + wid) >= ps->root_width && (y + hei) >= ps->root_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_ignore(session_t *ps, unsigned long sequence) {
|
static void set_ignore(session_t *ps, unsigned long sequence) {
|
||||||
|
@ -791,23 +779,6 @@ static inline void set_ignore_cookie(session_t *ps, xcb_void_cookie_t cookie) {
|
||||||
set_ignore(ps, cookie.sequence);
|
set_ignore(ps, cookie.sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a window is a fullscreen window.
|
|
||||||
*
|
|
||||||
* It's not using w->border_size for performance measures.
|
|
||||||
*/
|
|
||||||
static inline bool win_is_fullscreen(session_t *ps, const win *w) {
|
|
||||||
return rect_is_fullscreen(ps, w->g.x, w->g.y, w->widthb, w->heightb) &&
|
|
||||||
(!w->bounding_shaped || w->rounded_corners);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a window will be painted solid.
|
|
||||||
*/
|
|
||||||
static inline bool win_is_solid(session_t *ps, const win *w) {
|
|
||||||
return WMODE_SOLID == w->mode && !ps->o.force_win_blend;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if a window has a specific property.
|
* Determine if a window has a specific property.
|
||||||
*
|
*
|
||||||
|
@ -864,13 +835,6 @@ void vsync_deinit(session_t *ps);
|
||||||
/** @name DBus hooks
|
/** @name DBus hooks
|
||||||
*/
|
*/
|
||||||
///@{
|
///@{
|
||||||
void win_set_shadow_force(session_t *ps, win *w, switch_t val);
|
|
||||||
|
|
||||||
void win_set_fade_force(session_t *ps, win *w, switch_t val);
|
|
||||||
|
|
||||||
void win_set_focused_force(session_t *ps, win *w, switch_t val);
|
|
||||||
|
|
||||||
void win_set_invert_color_force(session_t *ps, win *w, switch_t val);
|
|
||||||
|
|
||||||
void opts_init_track_focus(session_t *ps);
|
void opts_init_track_focus(session_t *ps);
|
||||||
|
|
||||||
|
|
218
src/compton.c
218
src/compton.c
|
@ -154,11 +154,11 @@ void cxinerama_upd_scrs(session_t *ps) {
|
||||||
*
|
*
|
||||||
* XXX move to win.c
|
* XXX move to win.c
|
||||||
*/
|
*/
|
||||||
static inline win *find_win_all(session_t *ps, const xcb_window_t wid) {
|
static inline struct managed_win *find_win_all(session_t *ps, const xcb_window_t wid) {
|
||||||
if (!wid || PointerRoot == wid || wid == ps->root || wid == ps->overlay)
|
if (!wid || PointerRoot == wid || wid == ps->root || wid == ps->overlay)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
win *w = find_win(ps, wid);
|
auto w = find_managed_win(ps, wid);
|
||||||
if (!w)
|
if (!w)
|
||||||
w = find_toplevel(ps, wid);
|
w = find_toplevel(ps, wid);
|
||||||
if (!w)
|
if (!w)
|
||||||
|
@ -217,8 +217,8 @@ static double fade_timeout(session_t *ps) {
|
||||||
* @param steps steps of fading
|
* @param steps steps of fading
|
||||||
* @return whether we are still in fading mode
|
* @return whether we are still in fading mode
|
||||||
*/
|
*/
|
||||||
static bool run_fade(session_t *ps, win **_w, long steps) {
|
static bool run_fade(session_t *ps, struct managed_win **_w, long steps) {
|
||||||
win *w = *_w;
|
auto w = *_w;
|
||||||
if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) {
|
if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) {
|
||||||
// We are not fading
|
// We are not fading
|
||||||
assert(w->opacity_tgt == w->opacity);
|
assert(w->opacity_tgt == w->opacity);
|
||||||
|
@ -226,14 +226,14 @@ static bool run_fade(session_t *ps, win **_w, long steps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!win_should_fade(ps, w)) {
|
if (!win_should_fade(ps, w)) {
|
||||||
log_debug("Window %#010x %s doesn't need fading", w->id, w->name);
|
log_debug("Window %#010x %s doesn't need fading", w->base.id, w->name);
|
||||||
w->opacity = w->opacity_tgt;
|
w->opacity = w->opacity_tgt;
|
||||||
}
|
}
|
||||||
if (w->opacity == w->opacity_tgt) {
|
if (w->opacity == w->opacity_tgt) {
|
||||||
// We have reached target opacity.
|
// We have reached target opacity.
|
||||||
// We don't call win_check_fade_finished here because that could destroy
|
// We don't call win_check_fade_finished here because that could destroy
|
||||||
// the window, but we still need the damage info from this window
|
// the window, but we still need the damage info from this window
|
||||||
log_debug("Fading finished for window %#010x %s", w->id, w->name);
|
log_debug("Fading finished for window %#010x %s", w->base.id, w->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,11 +281,11 @@ static int should_ignore(session_t *ps, unsigned long sequence) {
|
||||||
*/
|
*/
|
||||||
uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) {
|
uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) {
|
||||||
uint32_t evmask = 0;
|
uint32_t evmask = 0;
|
||||||
win *w = NULL;
|
struct managed_win *w = NULL;
|
||||||
|
|
||||||
// Check if it's a mapped frame window
|
// Check if it's a mapped frame window
|
||||||
if (WIN_EVMODE_FRAME == mode ||
|
if (WIN_EVMODE_FRAME == mode ||
|
||||||
((w = find_win(ps, wid)) && w->a.map_state == XCB_MAP_STATE_VIEWABLE)) {
|
((w = find_managed_win(ps, wid)) && w->a.map_state == XCB_MAP_STATE_VIEWABLE)) {
|
||||||
evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE;
|
evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
if (ps->o.track_focus && !ps->o.use_ewmh_active_win)
|
if (ps->o.track_focus && !ps->o.use_ewmh_active_win)
|
||||||
evmask |= XCB_EVENT_MASK_FOCUS_CHANGE;
|
evmask |= XCB_EVENT_MASK_FOCUS_CHANGE;
|
||||||
|
@ -302,38 +302,6 @@ uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) {
|
||||||
return evmask;
|
return evmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Find out the WM frame of a client window by querying X.
|
|
||||||
*
|
|
||||||
* @param ps current session
|
|
||||||
* @param wid window ID
|
|
||||||
* @return struct _win object of the found window, NULL if not found
|
|
||||||
*/
|
|
||||||
win *find_toplevel2(session_t *ps, xcb_window_t wid) {
|
|
||||||
// TODO this should probably be an "update tree", then find_toplevel.
|
|
||||||
// current approach is a bit more "racy"
|
|
||||||
win *w = NULL;
|
|
||||||
|
|
||||||
// We traverse through its ancestors to find out the frame
|
|
||||||
while (wid && wid != ps->root && !(w = find_win(ps, wid))) {
|
|
||||||
xcb_query_tree_reply_t *reply;
|
|
||||||
|
|
||||||
// xcb_query_tree probably fails if you run compton when X is somehow
|
|
||||||
// initializing (like add it in .xinitrc). In this case
|
|
||||||
// just leave it alone.
|
|
||||||
reply = xcb_query_tree_reply(ps->c, xcb_query_tree(ps->c, wid), NULL);
|
|
||||||
if (reply == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
wid = reply->parent;
|
|
||||||
|
|
||||||
free(reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recheck currently focused window and set its <code>w->focused</code>
|
* Recheck currently focused window and set its <code>w->focused</code>
|
||||||
* to true.
|
* to true.
|
||||||
|
@ -341,7 +309,7 @@ win *find_toplevel2(session_t *ps, xcb_window_t wid) {
|
||||||
* @param ps current session
|
* @param ps current session
|
||||||
* @return struct _win of currently focused window, NULL if not found
|
* @return struct _win of currently focused window, NULL if not found
|
||||||
*/
|
*/
|
||||||
win *recheck_focus(session_t *ps) {
|
struct managed_win *recheck_focus(session_t *ps) {
|
||||||
// Use EWMH _NET_ACTIVE_WINDOW if enabled
|
// Use EWMH _NET_ACTIVE_WINDOW if enabled
|
||||||
if (ps->o.use_ewmh_active_win) {
|
if (ps->o.use_ewmh_active_win) {
|
||||||
update_ewmh_active_win(ps);
|
update_ewmh_active_win(ps);
|
||||||
|
@ -359,10 +327,10 @@ win *recheck_focus(session_t *ps) {
|
||||||
free(reply);
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
win *w = find_win_all(ps, wid);
|
auto w = find_win_all(ps, wid);
|
||||||
|
|
||||||
log_trace("%#010" PRIx32 " (%#010lx \"%s\") focused.", wid,
|
log_trace("%#010" PRIx32 " (%#010lx \"%s\") focused.", wid,
|
||||||
(w ? w->id : XCB_NONE), (w ? w->name : NULL));
|
(w ? w->base.id : XCB_NONE), (w ? w->name : NULL));
|
||||||
|
|
||||||
// And we set the focus state here
|
// And we set the focus state here
|
||||||
if (w) {
|
if (w) {
|
||||||
|
@ -418,10 +386,10 @@ static void handle_root_flags(session_t *ps) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static win *paint_preprocess(session_t *ps, bool *fade_running) {
|
static struct managed_win *paint_preprocess(session_t *ps, bool *fade_running) {
|
||||||
// XXX need better, more general name for `fade_running`. It really
|
// XXX need better, more general name for `fade_running`. It really
|
||||||
// means if fade is still ongoing after the current frame is rendered
|
// means if fade is still ongoing after the current frame is rendered
|
||||||
win *t = NULL;
|
struct managed_win *bottom = NULL;
|
||||||
*fade_running = false;
|
*fade_running = false;
|
||||||
|
|
||||||
// Fading step calculation
|
// Fading step calculation
|
||||||
|
@ -438,7 +406,7 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
|
||||||
ps->fade_time += steps * ps->o.fade_delta;
|
ps->fade_time += steps * ps->o.fade_delta;
|
||||||
|
|
||||||
// First, let's process fading
|
// First, let's process fading
|
||||||
list_foreach_safe(win, w, &ps->window_stack, stack_neighbour) {
|
win_stack_foreach_managed_safe(w, &ps->window_stack) {
|
||||||
const winmode_t mode_old = w->mode;
|
const winmode_t mode_old = w->mode;
|
||||||
const bool was_painted = w->to_paint;
|
const bool was_painted = w->to_paint;
|
||||||
const double opacity_old = w->opacity;
|
const double opacity_old = w->opacity;
|
||||||
|
@ -491,7 +459,7 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
|
||||||
// Track whether it's the highest window to paint
|
// Track whether it's the highest window to paint
|
||||||
bool is_highest = true;
|
bool is_highest = true;
|
||||||
bool reg_ignore_valid = true;
|
bool reg_ignore_valid = true;
|
||||||
list_foreach(win, w, &ps->window_stack, stack_neighbour) {
|
win_stack_foreach_managed(w, &ps->window_stack) {
|
||||||
__label__ skip_window;
|
__label__ skip_window;
|
||||||
bool to_paint = true;
|
bool to_paint = true;
|
||||||
// w->to_paint remembers whether this window is painted last time
|
// w->to_paint remembers whether this window is painted last time
|
||||||
|
@ -520,10 +488,10 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
|
||||||
// log_trace("%s %d %d %d", w->name, to_paint, w->opacity,
|
// log_trace("%s %d %d %d", w->name, to_paint, w->opacity,
|
||||||
// w->paint_excluded);
|
// w->paint_excluded);
|
||||||
|
|
||||||
if ((w->flags & WIN_FLAGS_STALE_IMAGE) != 0 &&
|
if ((w->flags & WIN_FLAGS_IMAGE_STALE) != 0 &&
|
||||||
(w->flags & WIN_FLAGS_IMAGE_ERROR) == 0 && to_paint) {
|
(w->flags & WIN_FLAGS_IMAGE_ERROR) == 0 && to_paint) {
|
||||||
// Image needs to be updated, update it.
|
// Image needs to be updated, update it.
|
||||||
w->flags &= ~WIN_FLAGS_STALE_IMAGE;
|
w->flags &= ~WIN_FLAGS_IMAGE_STALE;
|
||||||
if (w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING) {
|
if (w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING) {
|
||||||
// Rebind image only when the window does have an image
|
// Rebind image only when the window does have an image
|
||||||
// available
|
// available
|
||||||
|
@ -584,8 +552,8 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
|
||||||
unredir_possible = true;
|
unredir_possible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->prev_trans = t;
|
w->prev_trans = bottom;
|
||||||
t = w;
|
bottom = w;
|
||||||
|
|
||||||
// If the screen is not redirected and the window has redir_ignore set,
|
// If the screen is not redirected and the window has redir_ignore set,
|
||||||
// this window should not cause the screen to become redirected
|
// this window should not cause the screen to become redirected
|
||||||
|
@ -633,7 +601,7 @@ static win *paint_preprocess(session_t *ps, bool *fade_running) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -652,7 +620,7 @@ static void rebuild_shadow_exclude_reg(session_t *ps) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
static void restack_win(session_t *ps, struct win *w, xcb_window_t new_above) {
|
||||||
xcb_window_t old_above;
|
xcb_window_t old_above;
|
||||||
|
|
||||||
if (!list_node_is_last(&ps->window_stack, &w->stack_neighbour)) {
|
if (!list_node_is_last(&ps->window_stack, &w->stack_neighbour)) {
|
||||||
|
@ -661,13 +629,21 @@ static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||||
old_above = XCB_NONE;
|
old_above = XCB_NONE;
|
||||||
}
|
}
|
||||||
log_debug("Restack %#010x (%s), old_above: %#010x, new_above: %#010x", w->id,
|
log_debug("Restack %#010x (%s), old_above: %#010x, new_above: %#010x", w->id,
|
||||||
w->name, old_above, new_above);
|
win_get_name_if_managed(w), old_above, new_above);
|
||||||
|
|
||||||
|
struct managed_win *mw = NULL;
|
||||||
|
if (w->managed) {
|
||||||
|
mw = (struct managed_win *)w;
|
||||||
|
}
|
||||||
|
|
||||||
if (old_above != new_above) {
|
if (old_above != new_above) {
|
||||||
w->reg_ignore_valid = false;
|
if (mw) {
|
||||||
rc_region_unref(&w->reg_ignore);
|
mw->reg_ignore_valid = false;
|
||||||
if (!list_node_is_last(&ps->window_stack, &w->stack_neighbour)) {
|
rc_region_unref(&mw->reg_ignore);
|
||||||
auto next_w = list_next_entry(w, stack_neighbour);
|
}
|
||||||
|
|
||||||
|
auto next_w = win_stack_find_next_managed(ps, &w->stack_neighbour);
|
||||||
|
if (next_w) {
|
||||||
next_w->reg_ignore_valid = false;
|
next_w->reg_ignore_valid = false;
|
||||||
rc_region_unref(&next_w->reg_ignore);
|
rc_region_unref(&next_w->reg_ignore);
|
||||||
}
|
}
|
||||||
|
@ -676,7 +652,7 @@ static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||||
if (!new_above) {
|
if (!new_above) {
|
||||||
new_next = &ps->window_stack;
|
new_next = &ps->window_stack;
|
||||||
} else {
|
} else {
|
||||||
win *tmp_w = NULL;
|
struct win *tmp_w = NULL;
|
||||||
HASH_FIND_INT(ps->windows, &new_above, tmp_w);
|
HASH_FIND_INT(ps->windows, &new_above, tmp_w);
|
||||||
|
|
||||||
if (!tmp_w) {
|
if (!tmp_w) {
|
||||||
|
@ -692,11 +668,13 @@ static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||||
list_move_before(&w->stack_neighbour, new_next);
|
list_move_before(&w->stack_neighbour, new_next);
|
||||||
|
|
||||||
// add damage for this window
|
// add damage for this window
|
||||||
add_damage_from_win(ps, w);
|
if (mw) {
|
||||||
|
add_damage_from_win(ps, mw);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_RESTACK
|
#ifdef DEBUG_RESTACK
|
||||||
log_trace("Window stack modified. Current stack:");
|
log_trace("Window stack modified. Current stack:");
|
||||||
for (win *c = ps->list; c; c = c->next) {
|
for (auto c = ps->list; c; c = c->next) {
|
||||||
const char *desc = "";
|
const char *desc = "";
|
||||||
if (c->state == WSTATE_DESTROYING) {
|
if (c->state == WSTATE_DESTROYING) {
|
||||||
desc = "(D) ";
|
desc = "(D) ";
|
||||||
|
@ -709,7 +687,7 @@ static void restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||||
|
|
||||||
/// Free up all the images and deinit the backend
|
/// Free up all the images and deinit the backend
|
||||||
static void destroy_backend(session_t *ps) {
|
static void destroy_backend(session_t *ps) {
|
||||||
list_foreach_safe(win, w, &ps->window_stack, stack_neighbour) {
|
win_stack_foreach_managed_safe(w, &ps->window_stack) {
|
||||||
// Wrapping up fading in progress
|
// Wrapping up fading in progress
|
||||||
win_skip_fading(ps, &w);
|
win_skip_fading(ps, &w);
|
||||||
|
|
||||||
|
@ -757,7 +735,11 @@ static bool initialize_backend(session_t *ps) {
|
||||||
|
|
||||||
// window_stack shouldn't include window that's not in the hash table at
|
// window_stack shouldn't include window that's not in the hash table at
|
||||||
// this point. Since there cannot be any fading windows.
|
// this point. Since there cannot be any fading windows.
|
||||||
HASH_ITER2(ps->windows, w) {
|
HASH_ITER2(ps->windows, _w) {
|
||||||
|
if (!_w->managed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto w = (struct managed_win *)_w;
|
||||||
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
||||||
if (!win_bind_image(ps, w)) {
|
if (!win_bind_image(ps, w)) {
|
||||||
w->flags |= WIN_FLAGS_IMAGE_ERROR;
|
w->flags |= WIN_FLAGS_IMAGE_ERROR;
|
||||||
|
@ -797,8 +779,8 @@ void configure_root(session_t *ps, int width, int height) {
|
||||||
ps->damage = ps->damage_ring + ps->ndamage - 1;
|
ps->damage = ps->damage_ring + ps->ndamage - 1;
|
||||||
|
|
||||||
// Invalidate reg_ignore from the top
|
// Invalidate reg_ignore from the top
|
||||||
if (!list_is_empty(&ps->window_stack)) {
|
auto top_w = win_stack_find_next_managed(ps, &ps->window_stack);
|
||||||
auto top_w = list_entry(ps->window_stack.next, win, stack_neighbour);
|
if (top_w) {
|
||||||
rc_region_unref(&top_w->reg_ignore);
|
rc_region_unref(&top_w->reg_ignore);
|
||||||
top_w->reg_ignore_valid = false;
|
top_w->reg_ignore_valid = false;
|
||||||
}
|
}
|
||||||
|
@ -831,7 +813,7 @@ void configure_root(session_t *ps, int width, int height) {
|
||||||
|
|
||||||
/// Handle configure event of a regular window
|
/// Handle configure event of a regular window
|
||||||
void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||||
win *w = find_win(ps, ce->window);
|
auto w = find_managed_win(ps, ce->window);
|
||||||
region_t damage;
|
region_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
|
|
||||||
|
@ -843,9 +825,9 @@ void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||||
w->state == WSTATE_DESTROYING) {
|
w->state == WSTATE_DESTROYING) {
|
||||||
// Only restack the window to make sure we can handle future restack
|
// Only restack the window to make sure we can handle future restack
|
||||||
// notification correctly
|
// notification correctly
|
||||||
restack_win(ps, w, ce->above_sibling);
|
restack_win(ps, &w->base, ce->above_sibling);
|
||||||
} else {
|
} else {
|
||||||
restack_win(ps, w, ce->above_sibling);
|
restack_win(ps, &w->base, ce->above_sibling);
|
||||||
bool factor_change = false;
|
bool factor_change = false;
|
||||||
win_extents(w, &damage);
|
win_extents(w, &damage);
|
||||||
|
|
||||||
|
@ -889,14 +871,14 @@ void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void circulate_win(session_t *ps, xcb_circulate_notify_event_t *ce) {
|
void circulate_win(session_t *ps, xcb_circulate_notify_event_t *ce) {
|
||||||
win *w = find_win(ps, ce->window);
|
auto w = find_win(ps, ce->window);
|
||||||
xcb_window_t new_above;
|
xcb_window_t new_above;
|
||||||
|
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ce->place == PlaceOnTop) {
|
if (ce->place == PlaceOnTop) {
|
||||||
new_above = list_entry(ps->window_stack.next, win, stack_neighbour)->id;
|
new_above = list_entry(ps->window_stack.next, struct win, stack_neighbour)->id;
|
||||||
} else {
|
} else {
|
||||||
new_above = XCB_NONE;
|
new_above = XCB_NONE;
|
||||||
}
|
}
|
||||||
|
@ -962,48 +944,6 @@ void force_repaint(session_t *ps) {
|
||||||
*/
|
*/
|
||||||
///@{
|
///@{
|
||||||
|
|
||||||
/**
|
|
||||||
* Set w->shadow_force of a window.
|
|
||||||
*/
|
|
||||||
void win_set_shadow_force(session_t *ps, win *w, switch_t val) {
|
|
||||||
if (val != w->shadow_force) {
|
|
||||||
w->shadow_force = val;
|
|
||||||
win_determine_shadow(ps, w);
|
|
||||||
queue_redraw(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set w->fade_force of a window.
|
|
||||||
*
|
|
||||||
* Doesn't affect fading already in progress
|
|
||||||
*/
|
|
||||||
void win_set_fade_force(session_t *ps, win *w, switch_t val) {
|
|
||||||
w->fade_force = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set w->focused_force of a window.
|
|
||||||
*/
|
|
||||||
void win_set_focused_force(session_t *ps, win *w, switch_t val) {
|
|
||||||
if (val != w->focused_force) {
|
|
||||||
w->focused_force = val;
|
|
||||||
win_update_focused(ps, w);
|
|
||||||
queue_redraw(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set w->invert_color_force of a window.
|
|
||||||
*/
|
|
||||||
void win_set_invert_color_force(session_t *ps, win *w, switch_t val) {
|
|
||||||
if (val != w->invert_color_force) {
|
|
||||||
w->invert_color_force = val;
|
|
||||||
win_determine_invert_color(ps, w);
|
|
||||||
queue_redraw(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable focus tracking.
|
* Enable focus tracking.
|
||||||
*/
|
*/
|
||||||
|
@ -1017,7 +957,11 @@ void opts_init_track_focus(session_t *ps) {
|
||||||
if (!ps->o.use_ewmh_active_win) {
|
if (!ps->o.use_ewmh_active_win) {
|
||||||
// Start listening to FocusChange events
|
// Start listening to FocusChange events
|
||||||
HASH_ITER2(ps->windows, w) {
|
HASH_ITER2(ps->windows, w) {
|
||||||
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
if (!w->managed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto mw = (struct managed_win *)w;
|
||||||
|
if (mw->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
||||||
xcb_change_window_attributes(
|
xcb_change_window_attributes(
|
||||||
ps->c, w->id, XCB_CW_EVENT_MASK,
|
ps->c, w->id, XCB_CW_EVENT_MASK,
|
||||||
(const uint32_t[]){
|
(const uint32_t[]){
|
||||||
|
@ -1053,12 +997,13 @@ void opts_set_no_fading_openclose(session_t *ps, bool newval) {
|
||||||
void update_ewmh_active_win(session_t *ps) {
|
void update_ewmh_active_win(session_t *ps) {
|
||||||
// Search for the window
|
// Search for the window
|
||||||
xcb_window_t wid = wid_get_prop_window(ps, ps->root, ps->atom_ewmh_active_win);
|
xcb_window_t wid = wid_get_prop_window(ps, ps->root, ps->atom_ewmh_active_win);
|
||||||
win *w = find_win_all(ps, wid);
|
auto w = find_win_all(ps, wid);
|
||||||
|
|
||||||
// Mark the window focused. No need to unfocus the previous one.
|
// Mark the window focused. No need to unfocus the previous one.
|
||||||
if (w)
|
if (w) {
|
||||||
win_set_focused(ps, w, true);
|
win_set_focused(ps, w, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// === Main ===
|
// === Main ===
|
||||||
|
|
||||||
|
@ -1437,12 +1382,12 @@ static void fade_timer_callback(EV_P_ ev_timer *w, int revents) {
|
||||||
static void _draw_callback(EV_P_ session_t *ps, int revents) {
|
static void _draw_callback(EV_P_ session_t *ps, int revents) {
|
||||||
if (ps->o.benchmark) {
|
if (ps->o.benchmark) {
|
||||||
if (ps->o.benchmark_wid) {
|
if (ps->o.benchmark_wid) {
|
||||||
win *wi = find_win(ps, ps->o.benchmark_wid);
|
auto w = find_managed_win(ps, ps->o.benchmark_wid);
|
||||||
if (!wi) {
|
if (!w) {
|
||||||
log_fatal("Couldn't find specified benchmark window.");
|
log_fatal("Couldn't find specified benchmark window.");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
add_damage_from_win(ps, wi);
|
add_damage_from_win(ps, w);
|
||||||
} else {
|
} else {
|
||||||
force_repaint(ps);
|
force_repaint(ps);
|
||||||
}
|
}
|
||||||
|
@ -1458,7 +1403,7 @@ static void _draw_callback(EV_P_ session_t *ps, int revents) {
|
||||||
// should be redirected.
|
// should be redirected.
|
||||||
bool fade_running = false;
|
bool fade_running = false;
|
||||||
bool was_redirected = ps->redirected;
|
bool was_redirected = ps->redirected;
|
||||||
win *t = paint_preprocess(ps, &fade_running);
|
auto bottom = paint_preprocess(ps, &fade_running);
|
||||||
ps->tmout_unredir_hit = false;
|
ps->tmout_unredir_hit = false;
|
||||||
|
|
||||||
if (!was_redirected && ps->redirected) {
|
if (!was_redirected && ps->redirected) {
|
||||||
|
@ -1467,7 +1412,7 @@ static void _draw_callback(EV_P_ session_t *ps, int revents) {
|
||||||
// window would be put into an error state). so we rerun paint_preprocess
|
// window would be put into an error state). so we rerun paint_preprocess
|
||||||
// here to make sure the rendering decision we make is up-to-date
|
// here to make sure the rendering decision we make is up-to-date
|
||||||
log_debug("Re-run paint_preprocess");
|
log_debug("Re-run paint_preprocess");
|
||||||
t = paint_preprocess(ps, &fade_running);
|
bottom = paint_preprocess(ps, &fade_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start/stop fade timer depends on whether window are fading
|
// Start/stop fade timer depends on whether window are fading
|
||||||
|
@ -1482,9 +1427,9 @@ static void _draw_callback(EV_P_ session_t *ps, int revents) {
|
||||||
if (ps->redirected && ps->o.stoppaint_force != ON) {
|
if (ps->redirected && ps->o.stoppaint_force != ON) {
|
||||||
static int paint = 0;
|
static int paint = 0;
|
||||||
if (ps->o.experimental_backends) {
|
if (ps->o.experimental_backends) {
|
||||||
paint_all_new(ps, t, false);
|
paint_all_new(ps, bottom, false);
|
||||||
} else {
|
} else {
|
||||||
paint_all(ps, t, false);
|
paint_all(ps, bottom, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
paint++;
|
paint++;
|
||||||
|
@ -2122,21 +2067,29 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
children = NULL;
|
children = NULL;
|
||||||
nchildren = 0;
|
nchildren = 0;
|
||||||
}
|
}
|
||||||
|
free(reply);
|
||||||
|
|
||||||
for (int i = 0; i < nchildren; i++) {
|
for (int i = 0; i < nchildren; i++) {
|
||||||
add_win(ps, children[i], i ? children[i - 1] : XCB_NONE);
|
auto w =
|
||||||
|
add_win_above(ps, children[i], i ? children[i - 1] : XCB_NONE);
|
||||||
|
fill_win(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
HASH_ITER2(ps->windows, w) {
|
HASH_ITER2(ps->windows, w) {
|
||||||
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
assert(!w->is_new);
|
||||||
map_win(ps, w);
|
if (!w->managed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto mw = (struct managed_win *)w;
|
||||||
|
if (mw->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
||||||
|
map_win(ps, mw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(reply);
|
|
||||||
log_trace("Initial stack:");
|
log_trace("Initial stack:");
|
||||||
list_foreach(win, w, &ps->window_stack, stack_neighbour) {
|
list_foreach(struct win, w, &ps->window_stack, stack_neighbour) {
|
||||||
log_trace("%#010x \"%s\"", w->id, w->name);
|
log_trace("%#010x \"%s\"", w->id,
|
||||||
|
w->managed ? ((struct managed_win *)w)->name : "(null)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2186,13 +2139,16 @@ static void session_destroy(session_t *ps) {
|
||||||
|
|
||||||
// Free window linked list
|
// Free window linked list
|
||||||
|
|
||||||
list_foreach_safe(win, w, &ps->window_stack, stack_neighbour) {
|
list_foreach_safe(struct win, w, &ps->window_stack, stack_neighbour) {
|
||||||
if (w->state != WSTATE_DESTROYING) {
|
if (!w->destroyed) {
|
||||||
win_ev_stop(ps, w);
|
win_ev_stop(ps, w);
|
||||||
HASH_DEL(ps->windows, w);
|
HASH_DEL(ps->windows, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_win_res(ps, w);
|
if (w->managed) {
|
||||||
|
auto mw = (struct managed_win *)w;
|
||||||
|
free_win_res(ps, mw);
|
||||||
|
}
|
||||||
free(w);
|
free(w);
|
||||||
}
|
}
|
||||||
list_init_head(&ps->window_stack);
|
list_init_head(&ps->window_stack);
|
||||||
|
|
|
@ -42,9 +42,7 @@ uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode);
|
||||||
|
|
||||||
xcb_window_t find_client_win(session_t *ps, xcb_window_t w);
|
xcb_window_t find_client_win(session_t *ps, xcb_window_t w);
|
||||||
|
|
||||||
win *find_toplevel2(session_t *ps, xcb_window_t wid);
|
struct managed_win *recheck_focus(session_t *ps);
|
||||||
|
|
||||||
win *recheck_focus(session_t *ps);
|
|
||||||
|
|
||||||
/// Handle configure event of a root window
|
/// Handle configure event of a root window
|
||||||
void configure_root(session_t *ps, int width, int height);
|
void configure_root(session_t *ps, int width, int height);
|
||||||
|
|
46
src/dbus.c
46
src/dbus.c
|
@ -21,13 +21,13 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "uthash_extra.h"
|
#include "uthash_extra.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ static bool cdbus_apdarg_wids(session_t *ps, DBusMessage *msg, const void *data)
|
||||||
// Get the number of wids we are to include
|
// Get the number of wids we are to include
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
HASH_ITER2(ps->windows, w) {
|
HASH_ITER2(ps->windows, w) {
|
||||||
assert(w->state != WSTATE_DESTROYING);
|
assert(!w->destroyed);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ static bool cdbus_apdarg_wids(session_t *ps, DBusMessage *msg, const void *data)
|
||||||
// Build the array
|
// Build the array
|
||||||
cdbus_window_t *pcur = arr;
|
cdbus_window_t *pcur = arr;
|
||||||
HASH_ITER2(ps->windows, w) {
|
HASH_ITER2(ps->windows, w) {
|
||||||
assert(w->state != WSTATE_DESTROYING);
|
assert(!w->destroyed);
|
||||||
*pcur = w->id;
|
*pcur = w->id;
|
||||||
++pcur;
|
++pcur;
|
||||||
}
|
}
|
||||||
|
@ -743,7 +743,7 @@ static bool cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
win *w = find_win(ps, wid);
|
auto w = find_managed_win(ps, wid);
|
||||||
|
|
||||||
if (!w) {
|
if (!w) {
|
||||||
log_error("Window %#010x not found.", wid);
|
log_error("Window %#010x not found.", wid);
|
||||||
|
@ -757,14 +757,16 @@ static bool cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
|
||||||
return true; \
|
return true; \
|
||||||
}
|
}
|
||||||
|
|
||||||
cdbus_m_win_get_do(id, cdbus_reply_wid);
|
cdbus_m_win_get_do(base.id, cdbus_reply_wid);
|
||||||
|
|
||||||
// next
|
// next
|
||||||
if (!strcmp("next", target)) {
|
if (!strcmp("next", target)) {
|
||||||
cdbus_reply_wid(ps, msg,
|
cdbus_reply_wid(
|
||||||
(list_node_is_last(&ps->window_stack, &w->stack_neighbour)
|
ps, msg,
|
||||||
|
(list_node_is_last(&ps->window_stack, &w->base.stack_neighbour)
|
||||||
? 0
|
? 0
|
||||||
: list_next_entry(w, stack_neighbour)->id));
|
: list_entry(w->base.stack_neighbour.next, struct win, stack_neighbour)
|
||||||
|
->id));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +847,7 @@ static bool cdbus_process_win_set(session_t *ps, DBusMessage *msg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
win *w = find_win(ps, wid);
|
auto w = find_managed_win(ps, wid);
|
||||||
|
|
||||||
if (!w) {
|
if (!w) {
|
||||||
log_error("Window %#010x not found.", wid);
|
log_error("Window %#010x not found.", wid);
|
||||||
|
@ -922,15 +924,17 @@ static bool cdbus_process_find_win(session_t *ps, DBusMessage *msg) {
|
||||||
cdbus_window_t client = XCB_NONE;
|
cdbus_window_t client = XCB_NONE;
|
||||||
if (!cdbus_msg_get_arg(msg, 1, CDBUS_TYPE_WINDOW, &client))
|
if (!cdbus_msg_get_arg(msg, 1, CDBUS_TYPE_WINDOW, &client))
|
||||||
return false;
|
return false;
|
||||||
win *w = find_toplevel(ps, client);
|
auto w = find_toplevel(ps, client);
|
||||||
if (w)
|
if (w) {
|
||||||
wid = w->id;
|
wid = w->base.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Find focused window
|
// Find focused window
|
||||||
else if (!strcmp("focused", target)) {
|
else if (!strcmp("focused", target)) {
|
||||||
win *w = find_focused(ps);
|
auto w = find_focused(ps);
|
||||||
if (w)
|
if (w) {
|
||||||
wid = w->id;
|
wid = w->base.id;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log_error(CDBUS_ERROR_BADTGT_S, target);
|
log_error(CDBUS_ERROR_BADTGT_S, target);
|
||||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
|
||||||
|
@ -1301,37 +1305,37 @@ static DBusHandlerResult cdbus_process(DBusConnection *c, DBusMessage *msg, void
|
||||||
/** @name Core callbacks
|
/** @name Core callbacks
|
||||||
*/
|
*/
|
||||||
///@{
|
///@{
|
||||||
void cdbus_ev_win_added(session_t *ps, win *w) {
|
void cdbus_ev_win_added(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn)
|
||||||
cdbus_signal_wid(ps, "win_added", w->id);
|
cdbus_signal_wid(ps, "win_added", w->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_destroyed(session_t *ps, win *w) {
|
void cdbus_ev_win_destroyed(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn)
|
||||||
cdbus_signal_wid(ps, "win_destroyed", w->id);
|
cdbus_signal_wid(ps, "win_destroyed", w->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_mapped(session_t *ps, win *w) {
|
void cdbus_ev_win_mapped(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn)
|
||||||
cdbus_signal_wid(ps, "win_mapped", w->id);
|
cdbus_signal_wid(ps, "win_mapped", w->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_unmapped(session_t *ps, win *w) {
|
void cdbus_ev_win_unmapped(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn)
|
||||||
cdbus_signal_wid(ps, "win_unmapped", w->id);
|
cdbus_signal_wid(ps, "win_unmapped", w->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_focusout(session_t *ps, win *w) {
|
void cdbus_ev_win_focusout(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn)
|
||||||
cdbus_signal_wid(ps, "win_focusout", w->id);
|
cdbus_signal_wid(ps, "win_focusout", w->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdbus_ev_win_focusin(session_t *ps, win *w) {
|
void cdbus_ev_win_focusin(session_t *ps, struct win *w) {
|
||||||
struct cdbus_data *cd = ps->dbus_data;
|
struct cdbus_data *cd = ps->dbus_data;
|
||||||
if (cd->dbus_conn)
|
if (cd->dbus_conn)
|
||||||
cdbus_signal_wid(ps, "win_focusin", w->id);
|
cdbus_signal_wid(ps, "win_focusin", w->id);
|
||||||
|
|
14
src/dbus.h
14
src/dbus.h
|
@ -14,7 +14,7 @@
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
typedef struct win win;
|
struct win;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a string representation of a D-Bus message type.
|
* Return a string representation of a D-Bus message type.
|
||||||
|
@ -34,21 +34,21 @@ bool cdbus_init(session_t *ps, const char *uniq_name);
|
||||||
void cdbus_destroy(session_t *ps);
|
void cdbus_destroy(session_t *ps);
|
||||||
|
|
||||||
/// Generate dbus win_added signal
|
/// Generate dbus win_added signal
|
||||||
void cdbus_ev_win_added(session_t *ps, win *w);
|
void cdbus_ev_win_added(session_t *ps, struct win *w);
|
||||||
|
|
||||||
/// Generate dbus win_destroyed signal
|
/// Generate dbus win_destroyed signal
|
||||||
void cdbus_ev_win_destroyed(session_t *ps, win *w);
|
void cdbus_ev_win_destroyed(session_t *ps, struct win *w);
|
||||||
|
|
||||||
/// Generate dbus win_mapped signal
|
/// Generate dbus win_mapped signal
|
||||||
void cdbus_ev_win_mapped(session_t *ps, win *w);
|
void cdbus_ev_win_mapped(session_t *ps, struct win *w);
|
||||||
|
|
||||||
/// Generate dbus win_unmapped signal
|
/// Generate dbus win_unmapped signal
|
||||||
void cdbus_ev_win_unmapped(session_t *ps, win *w);
|
void cdbus_ev_win_unmapped(session_t *ps, struct win *w);
|
||||||
|
|
||||||
/// Generate dbus win_focusout signal
|
/// Generate dbus win_focusout signal
|
||||||
void cdbus_ev_win_focusout(session_t *ps, win *w);
|
void cdbus_ev_win_focusout(session_t *ps, struct win *w);
|
||||||
|
|
||||||
/// Generate dbus win_focusin signal
|
/// Generate dbus win_focusin signal
|
||||||
void cdbus_ev_win_focusin(session_t *ps, win *w);
|
void cdbus_ev_win_focusin(session_t *ps, struct win *w);
|
||||||
|
|
||||||
// vim: set noet sw=8 ts=8 :
|
// vim: set noet sw=8 ts=8 :
|
||||||
|
|
59
src/event.c
59
src/event.c
|
@ -50,7 +50,7 @@ static inline const char *ev_window_name(session_t *ps, xcb_window_t wid) {
|
||||||
} else if (ps->overlay == wid) {
|
} else if (ps->overlay == wid) {
|
||||||
name = "(Overlay)";
|
name = "(Overlay)";
|
||||||
} else {
|
} else {
|
||||||
win *w = find_win(ps, wid);
|
auto w = find_managed_win(ps, wid);
|
||||||
if (!w) {
|
if (!w) {
|
||||||
w = find_toplevel(ps, wid);
|
w = find_toplevel(ps, wid);
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,8 @@ static inline void ev_focus_out(session_t *ps, xcb_focus_out_event_t *ev) {
|
||||||
|
|
||||||
static inline void ev_create_notify(session_t *ps, xcb_create_notify_event_t *ev) {
|
static inline void ev_create_notify(session_t *ps, xcb_create_notify_event_t *ev) {
|
||||||
assert(ev->parent == ps->root);
|
assert(ev->parent == ps->root);
|
||||||
add_win(ps, ev->window, 0);
|
// TODO delay fill_win
|
||||||
|
fill_win(ps, add_win_top(ps, ev->window));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ev_configure_notify(session_t *ps, xcb_configure_notify_event_t *ev) {
|
static inline void ev_configure_notify(session_t *ps, xcb_configure_notify_event_t *ev) {
|
||||||
|
@ -183,7 +184,7 @@ static inline void ev_configure_notify(session_t *ps, xcb_configure_notify_event
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ev_destroy_notify(session_t *ps, xcb_destroy_notify_event_t *ev) {
|
static inline void ev_destroy_notify(session_t *ps, xcb_destroy_notify_event_t *ev) {
|
||||||
win *w = find_win(ps, ev->window);
|
auto w = find_managed_win(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
unmap_win(ps, &w, true);
|
unmap_win(ps, &w, true);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,7 @@ static inline void ev_map_notify(session_t *ps, xcb_map_notify_event_t *ev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ev_unmap_notify(session_t *ps, xcb_unmap_notify_event_t *ev) {
|
static inline void ev_unmap_notify(session_t *ps, xcb_unmap_notify_event_t *ev) {
|
||||||
win *w = find_win(ps, ev->window);
|
auto w = find_managed_win(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
unmap_win(ps, &w, false);
|
unmap_win(ps, &w, false);
|
||||||
}
|
}
|
||||||
|
@ -211,12 +212,13 @@ static inline void ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t
|
||||||
|
|
||||||
if (ev->parent == ps->root) {
|
if (ev->parent == ps->root) {
|
||||||
// new window
|
// new window
|
||||||
add_win(ps, ev->window, 0);
|
// TODO delay fill_win
|
||||||
|
fill_win(ps, add_win_top(ps, ev->window));
|
||||||
} else {
|
} else {
|
||||||
// otherwise, find and destroy the window first
|
// otherwise, find and destroy the window first
|
||||||
win *w = find_win(ps, ev->window);
|
auto w = find_win(ps, ev->window);
|
||||||
if (w) {
|
if (w && w->managed) {
|
||||||
unmap_win(ps, &w, true);
|
unmap_win(ps, (struct managed_win **)&w, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset event mask in case something wrong happens
|
// Reset event mask in case something wrong happens
|
||||||
|
@ -228,10 +230,10 @@ static inline void ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t
|
||||||
// Firstly, check if it's a known client window
|
// Firstly, check if it's a known client window
|
||||||
if (!find_toplevel(ps, ev->window)) {
|
if (!find_toplevel(ps, ev->window)) {
|
||||||
// If not, look for its frame window
|
// If not, look for its frame window
|
||||||
win *w_top = find_toplevel2(ps, ev->parent);
|
auto w_top = find_toplevel2(ps, ev->parent);
|
||||||
// If found, and the client window has not been determined, or its
|
// If found, and the client window has not been determined, or its
|
||||||
// frame may not have a correct client, continue
|
// frame may not have a correct client, continue
|
||||||
if (w_top && (!w_top->client_win || w_top->client_win == w_top->id)) {
|
if (w_top && (!w_top->client_win || w_top->client_win == w_top->base.id)) {
|
||||||
// If it has WM_STATE, mark it the client window
|
// If it has WM_STATE, mark it the client window
|
||||||
if (wid_has_prop(ps, ev->window, ps->atom_client)) {
|
if (wid_has_prop(ps, ev->window, ps->atom_client)) {
|
||||||
w_top->wmwin = false;
|
w_top->wmwin = false;
|
||||||
|
@ -328,9 +330,9 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
(const uint32_t[]){determine_evmask(
|
(const uint32_t[]){determine_evmask(
|
||||||
ps, ev->window, WIN_EVMODE_UNKNOWN)});
|
ps, ev->window, WIN_EVMODE_UNKNOWN)});
|
||||||
|
|
||||||
win *w_top = find_toplevel2(ps, ev->window);
|
auto w_top = find_toplevel2(ps, ev->window);
|
||||||
// Initialize client_win as early as possible
|
// Initialize client_win as early as possible
|
||||||
if (w_top && (!w_top->client_win || w_top->client_win == w_top->id) &&
|
if (w_top && (!w_top->client_win || w_top->client_win == w_top->base.id) &&
|
||||||
wid_has_prop(ps, ev->window, ps->atom_client)) {
|
wid_has_prop(ps, ev->window, ps->atom_client)) {
|
||||||
w_top->wmwin = false;
|
w_top->wmwin = false;
|
||||||
win_unmark_client(ps, w_top);
|
win_unmark_client(ps, w_top);
|
||||||
|
@ -342,14 +344,14 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
// If _NET_WM_WINDOW_TYPE changes... God knows why this would happen, but
|
// If _NET_WM_WINDOW_TYPE changes... God knows why this would happen, but
|
||||||
// there are always some stupid applications. (#144)
|
// there are always some stupid applications. (#144)
|
||||||
if (ev->atom == ps->atom_win_type) {
|
if (ev->atom == ps->atom_win_type) {
|
||||||
win *w = NULL;
|
struct managed_win *w = NULL;
|
||||||
if ((w = find_toplevel(ps, ev->window)))
|
if ((w = find_toplevel(ps, ev->window)))
|
||||||
win_update_wintype(ps, w);
|
win_update_wintype(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If _NET_WM_OPACITY changes
|
// If _NET_WM_OPACITY changes
|
||||||
if (ev->atom == ps->atom_opacity) {
|
if (ev->atom == ps->atom_opacity) {
|
||||||
win *w = find_win(ps, ev->window) ?: find_toplevel(ps, ev->window);
|
auto w = find_managed_win(ps, ev->window) ?: find_toplevel(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
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
|
||||||
|
@ -364,7 +366,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
|
|
||||||
// If frame extents property changes
|
// If frame extents property changes
|
||||||
if (ps->o.frame_opacity > 0 && ev->atom == ps->atom_frame_extents) {
|
if (ps->o.frame_opacity > 0 && ev->atom == ps->atom_frame_extents) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
auto w = find_toplevel(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
win_update_frame_extents(ps, w, ev->window);
|
win_update_frame_extents(ps, w, ev->window);
|
||||||
// If frame extents change, the window needs repaint
|
// If frame extents change, the window needs repaint
|
||||||
|
@ -374,7 +376,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
|
|
||||||
// If name changes
|
// If name changes
|
||||||
if (ps->o.track_wdata && (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) {
|
if (ps->o.track_wdata && (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
auto w = find_toplevel(ps, ev->window);
|
||||||
if (w && 1 == win_get_name(ps, w)) {
|
if (w && 1 == win_get_name(ps, w)) {
|
||||||
win_on_factor_change(ps, w);
|
win_on_factor_change(ps, w);
|
||||||
}
|
}
|
||||||
|
@ -382,7 +384,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
|
|
||||||
// If class changes
|
// If class changes
|
||||||
if (ps->o.track_wdata && ps->atom_class == ev->atom) {
|
if (ps->o.track_wdata && ps->atom_class == ev->atom) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
auto w = find_toplevel(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
win_get_class(ps, w);
|
win_get_class(ps, w);
|
||||||
win_on_factor_change(ps, w);
|
win_on_factor_change(ps, w);
|
||||||
|
@ -391,7 +393,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
|
|
||||||
// If role changes
|
// If role changes
|
||||||
if (ps->o.track_wdata && ps->atom_role == ev->atom) {
|
if (ps->o.track_wdata && ps->atom_role == ev->atom) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
auto w = find_toplevel(ps, ev->window);
|
||||||
if (w && 1 == win_get_role(ps, w)) {
|
if (w && 1 == win_get_role(ps, w)) {
|
||||||
win_on_factor_change(ps, w);
|
win_on_factor_change(ps, w);
|
||||||
}
|
}
|
||||||
|
@ -399,15 +401,16 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
|
|
||||||
// If _COMPTON_SHADOW changes
|
// If _COMPTON_SHADOW changes
|
||||||
if (ps->o.respect_prop_shadow && ps->atom_compton_shadow == ev->atom) {
|
if (ps->o.respect_prop_shadow && ps->atom_compton_shadow == ev->atom) {
|
||||||
win *w = find_win(ps, ev->window);
|
auto w = find_managed_win(ps, ev->window);
|
||||||
if (w)
|
if (w) {
|
||||||
win_update_prop_shadow(ps, w);
|
win_update_prop_shadow(ps, w);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If a leader property changes
|
// If a leader property changes
|
||||||
if ((ps->o.detect_transient && ps->atom_transient == ev->atom) ||
|
if ((ps->o.detect_transient && ps->atom_transient == ev->atom) ||
|
||||||
(ps->o.detect_client_leader && ps->atom_client_leader == ev->atom)) {
|
(ps->o.detect_client_leader && ps->atom_client_leader == ev->atom)) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
auto w = find_toplevel(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
win_update_leader(ps, w);
|
win_update_leader(ps, w);
|
||||||
}
|
}
|
||||||
|
@ -416,7 +419,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
// Check for other atoms we are tracking
|
// Check for other atoms we are tracking
|
||||||
for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
|
for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
|
||||||
if (platom->atom == ev->atom) {
|
if (platom->atom == ev->atom) {
|
||||||
win *w = find_win(ps, ev->window);
|
auto w = find_managed_win(ps, ev->window);
|
||||||
if (!w)
|
if (!w)
|
||||||
w = find_toplevel(ps, ev->window);
|
w = find_toplevel(ps, ev->window);
|
||||||
if (w)
|
if (w)
|
||||||
|
@ -426,7 +429,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void repair_win(session_t *ps, win *w) {
|
static inline void repair_win(session_t *ps, struct managed_win *w) {
|
||||||
if (w->a.map_state != XCB_MAP_STATE_VIEWABLE)
|
if (w->a.map_state != XCB_MAP_STATE_VIEWABLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -472,18 +475,20 @@ static inline void ev_damage_notify(session_t *ps, xcb_damage_notify_event_t *de
|
||||||
return;
|
return;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
win *w = find_win(ps, de->drawable);
|
auto w = find_managed_win(ps, de->drawable);
|
||||||
|
|
||||||
if (!w)
|
if (!w) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
repair_win(ps, w);
|
repair_win(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ev_shape_notify(session_t *ps, xcb_shape_notify_event_t *ev) {
|
static inline void ev_shape_notify(session_t *ps, xcb_shape_notify_event_t *ev) {
|
||||||
win *w = find_win(ps, ev->affected_window);
|
auto w = find_managed_win(ps, ev->affected_window);
|
||||||
if (!w || w->a.map_state == XCB_MAP_STATE_UNMAPPED)
|
if (!w || w->a.map_state == XCB_MAP_STATE_UNMAPPED) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Empty bounding_shape may indicated an
|
* Empty bounding_shape may indicated an
|
||||||
|
|
|
@ -221,7 +221,7 @@ void glx_destroy(session_t *ps) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Free all GLX resources of windows
|
// Free all GLX resources of windows
|
||||||
list_foreach(win, w, &ps->window_stack, stack_neighbour) {
|
win_stack_foreach_managed(w, &ps->window_stack) {
|
||||||
free_win_res_glx(ps, w);
|
free_win_res_glx(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ static inline void free_paint_glx(session_t *ps, paint_t *ppaint) {
|
||||||
/**
|
/**
|
||||||
* Free GLX part of win.
|
* Free GLX part of win.
|
||||||
*/
|
*/
|
||||||
static inline void free_win_res_glx(session_t *ps, win *w) {
|
static inline void free_win_res_glx(session_t *ps, struct managed_win *w) {
|
||||||
free_paint_glx(ps, &w->paint);
|
free_paint_glx(ps, &w->paint);
|
||||||
free_paint_glx(ps, &w->shadow_paint);
|
free_paint_glx(ps, &w->shadow_paint);
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
|
|
32
src/render.c
32
src/render.c
|
@ -197,8 +197,8 @@ void render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei, doubl
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paint_region(session_t *ps, win *w, int x, int y, int wid, int hei, double opacity,
|
paint_region(session_t *ps, const struct managed_win *w, int x, int y, int wid, int hei,
|
||||||
const region_t *reg_paint, xcb_render_picture_t pict) {
|
double opacity, const region_t *reg_paint, xcb_render_picture_t pict) {
|
||||||
const int dx = (w ? w->g.x : 0) + x;
|
const int dx = (w ? w->g.x : 0) + x;
|
||||||
const int dy = (w ? w->g.y : 0) + y;
|
const int dy = (w ? w->g.y : 0) + y;
|
||||||
const bool argb = (w && (win_has_alpha(w) || ps->o.force_win_blend));
|
const bool argb = (w && (win_has_alpha(w) || ps->o.force_win_blend));
|
||||||
|
@ -237,19 +237,19 @@ static inline bool paint_isvalid(session_t *ps, const paint_t *ppaint) {
|
||||||
/**
|
/**
|
||||||
* Paint a window itself and dim it if asked.
|
* Paint a window itself and dim it if asked.
|
||||||
*/
|
*/
|
||||||
void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
|
void paint_one(session_t *ps, struct managed_win *w, const region_t *reg_paint) {
|
||||||
// Fetch Pixmap
|
// Fetch Pixmap
|
||||||
if (!w->paint.pixmap) {
|
if (!w->paint.pixmap) {
|
||||||
w->paint.pixmap = x_new_id(ps->c);
|
w->paint.pixmap = x_new_id(ps->c);
|
||||||
set_ignore_cookie(
|
set_ignore_cookie(ps, xcb_composite_name_window_pixmap(ps->c, w->base.id,
|
||||||
ps, xcb_composite_name_window_pixmap(ps->c, w->id, w->paint.pixmap));
|
w->paint.pixmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_drawable_t draw = w->paint.pixmap;
|
xcb_drawable_t draw = w->paint.pixmap;
|
||||||
if (!draw) {
|
if (!draw) {
|
||||||
log_error("Failed to get pixmap from window %#010x (%s), window won't be "
|
log_error("Failed to get pixmap from window %#010x (%s), window won't be "
|
||||||
"visible",
|
"visible",
|
||||||
w->id, w->name);
|
w->base.id, w->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,12 +269,12 @@ void paint_one(session_t *ps, win *w, const region_t *reg_paint) {
|
||||||
// causing the jittering issue M4he reported in #7.
|
// causing the jittering issue M4he reported in #7.
|
||||||
if (!paint_bind_tex(ps, &w->paint, 0, 0, false, 0, w->a.visual,
|
if (!paint_bind_tex(ps, &w->paint, 0, 0, false, 0, w->a.visual,
|
||||||
(!ps->o.glx_no_rebind_pixmap && w->pixmap_damaged))) {
|
(!ps->o.glx_no_rebind_pixmap && w->pixmap_damaged))) {
|
||||||
log_error("Failed to bind texture for window %#010x.", w->id);
|
log_error("Failed to bind texture for window %#010x.", w->base.id);
|
||||||
}
|
}
|
||||||
w->pixmap_damaged = false;
|
w->pixmap_damaged = false;
|
||||||
|
|
||||||
if (!paint_isvalid(ps, &w->paint)) {
|
if (!paint_isvalid(ps, &w->paint)) {
|
||||||
log_error("Window %#010x is missing painting data.", w->id);
|
log_error("Window %#010x is missing painting data.", w->base.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ static void paint_root(session_t *ps, const region_t *reg_paint) {
|
||||||
/**
|
/**
|
||||||
* Generate shadow <code>Picture</code> for a window.
|
* Generate shadow <code>Picture</code> for a window.
|
||||||
*/
|
*/
|
||||||
static bool win_build_shadow(session_t *ps, win *w, double opacity) {
|
static bool win_build_shadow(session_t *ps, struct managed_win *w, double opacity) {
|
||||||
const int width = w->widthb;
|
const int width = w->widthb;
|
||||||
const int height = w->heightb;
|
const int height = w->heightb;
|
||||||
// log_trace("(): building shadow for %s %d %d", w->name, width, height);
|
// log_trace("(): building shadow for %s %d %d", w->name, width, height);
|
||||||
|
@ -577,12 +577,13 @@ shadow_picture_err:
|
||||||
/**
|
/**
|
||||||
* Paint the shadow of a window.
|
* Paint the shadow of a window.
|
||||||
*/
|
*/
|
||||||
static inline void win_paint_shadow(session_t *ps, win *w, region_t *reg_paint) {
|
static inline void
|
||||||
|
win_paint_shadow(session_t *ps, struct managed_win *w, region_t *reg_paint) {
|
||||||
// Bind shadow pixmap to GLX texture if needed
|
// Bind shadow pixmap to GLX texture if needed
|
||||||
paint_bind_tex(ps, &w->shadow_paint, 0, 0, false, 32, 0, false);
|
paint_bind_tex(ps, &w->shadow_paint, 0, 0, false, 32, 0, false);
|
||||||
|
|
||||||
if (!paint_isvalid(ps, &w->shadow_paint)) {
|
if (!paint_isvalid(ps, &w->shadow_paint)) {
|
||||||
log_error("Window %#010x is missing shadow data.", w->id);
|
log_error("Window %#010x is missing shadow data.", w->base.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,8 +665,9 @@ static bool xr_blur_dst(session_t *ps, xcb_render_picture_t tgt_buffer, int16_t
|
||||||
/**
|
/**
|
||||||
* Blur the background of a window.
|
* Blur the background of a window.
|
||||||
*/
|
*/
|
||||||
static inline void win_blur_background(session_t *ps, win *w, xcb_render_picture_t tgt_buffer,
|
static inline void
|
||||||
const region_t *reg_paint) {
|
win_blur_background(session_t *ps, struct managed_win *w,
|
||||||
|
xcb_render_picture_t tgt_buffer, const region_t *reg_paint) {
|
||||||
const int16_t x = w->g.x;
|
const int16_t x = w->g.x;
|
||||||
const int16_t y = w->g.y;
|
const int16_t y = w->g.y;
|
||||||
const auto wid = to_u16_checked(w->widthb);
|
const auto wid = to_u16_checked(w->widthb);
|
||||||
|
@ -770,7 +772,7 @@ static inline void resize_region(region_t *region, short mod) {
|
||||||
/// paint all windows
|
/// paint all windows
|
||||||
/// region = ??
|
/// region = ??
|
||||||
/// region_real = the damage region
|
/// region_real = the damage region
|
||||||
void paint_all(session_t *ps, win *const t, bool ignore_damage) {
|
void paint_all(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||||
if (ps->o.xrender_sync_fence) {
|
if (ps->o.xrender_sync_fence) {
|
||||||
if (ps->xsync_exists && !x_fence_sync(ps->c, ps->sync_fence)) {
|
if (ps->xsync_exists && !x_fence_sync(ps->c, ps->sync_fence)) {
|
||||||
log_error("x_fence_sync failed, xrender-sync-fence will be "
|
log_error("x_fence_sync failed, xrender-sync-fence will be "
|
||||||
|
@ -857,7 +859,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
|
||||||
// pixels painted.
|
// pixels painted.
|
||||||
//
|
//
|
||||||
// Whether this is beneficial is to be determined XXX
|
// Whether this is beneficial is to be determined XXX
|
||||||
for (win *w = t; w; w = w->prev_trans) {
|
for (auto w = t; w; w = w->prev_trans) {
|
||||||
region_t bshape = win_get_bounding_shape_global_by_val(w);
|
region_t bshape = win_get_bounding_shape_global_by_val(w);
|
||||||
// Painting shadow
|
// Painting shadow
|
||||||
if (w->shadow) {
|
if (w->shadow) {
|
||||||
|
|
|
@ -12,9 +12,10 @@
|
||||||
|
|
||||||
typedef struct _glx_texture glx_texture_t;
|
typedef struct _glx_texture glx_texture_t;
|
||||||
typedef struct glx_prog_main glx_prog_main_t;
|
typedef struct glx_prog_main glx_prog_main_t;
|
||||||
typedef struct win win;
|
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
|
|
||||||
|
struct managed_win;
|
||||||
|
|
||||||
typedef struct paint {
|
typedef struct paint {
|
||||||
xcb_pixmap_t pixmap;
|
xcb_pixmap_t pixmap;
|
||||||
xcb_render_picture_t pict;
|
xcb_render_picture_t pict;
|
||||||
|
@ -27,9 +28,9 @@ typedef struct paint {
|
||||||
void render(session_t *ps, int x, int y, int dx, int dy, int w, int h, double opacity,
|
void render(session_t *ps, int x, int y, int dx, int dy, int w, int h, double opacity,
|
||||||
bool argb, bool neg, xcb_render_picture_t pict, glx_texture_t *ptex,
|
bool argb, bool neg, xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||||
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
||||||
void paint_one(session_t *ps, win *w, const region_t *reg_paint);
|
void paint_one(session_t *ps, struct managed_win *w, const region_t *reg_paint);
|
||||||
|
|
||||||
void paint_all(session_t *ps, win *const t, bool ignore_damage);
|
void paint_all(session_t *ps, struct managed_win *const t, bool ignore_damage);
|
||||||
|
|
||||||
void free_picture(xcb_connection_t *c, xcb_render_picture_t *p);
|
void free_picture(xcb_connection_t *c, xcb_render_picture_t *p);
|
||||||
|
|
||||||
|
|
198
src/win.h
198
src/win.h
|
@ -17,16 +17,23 @@
|
||||||
#include "backend/backend.h"
|
#include "backend/backend.h"
|
||||||
#include "c2.h"
|
#include "c2.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
#include "list.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "x.h"
|
#include "x.h"
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
typedef struct _glx_texture glx_texture_t;
|
typedef struct _glx_texture glx_texture_t;
|
||||||
|
|
||||||
|
#define win_stack_foreach_managed(w, win_stack) \
|
||||||
|
list_foreach(struct managed_win, w, win_stack, base.stack_neighbour) if (w->base.managed)
|
||||||
|
|
||||||
|
#define win_stack_foreach_managed_safe(w, win_stack) \
|
||||||
|
list_foreach_safe(struct managed_win, w, win_stack, \
|
||||||
|
base.stack_neighbour) if (w->base.managed)
|
||||||
|
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
// FIXME this type should be in opengl.h
|
// FIXME this type should be in opengl.h
|
||||||
// it is very unideal for it to be here
|
// it is very unideal for it to be here
|
||||||
|
@ -108,15 +115,16 @@ typedef enum {
|
||||||
WSTATE_UNMAPPED,
|
WSTATE_UNMAPPED,
|
||||||
} winstate_t;
|
} winstate_t;
|
||||||
|
|
||||||
typedef enum win_flags {
|
enum win_flags {
|
||||||
/// win_image/shadow_image is out of date
|
/// win_image/shadow_image is out of date
|
||||||
WIN_FLAGS_STALE_IMAGE = 1,
|
WIN_FLAGS_IMAGE_STALE = 1,
|
||||||
/// there was an error trying to bind the images
|
/// there was an error trying to bind the images
|
||||||
WIN_FLAGS_IMAGE_ERROR = 2,
|
WIN_FLAGS_IMAGE_ERROR = 2,
|
||||||
} win_flags_t;
|
};
|
||||||
|
|
||||||
/// An entry in the window stack. May or may not correspond to a window we know about.
|
/// An entry in the window stack. May or may not correspond to a window we know about.
|
||||||
struct window_stack_entry {
|
struct window_stack_entry {
|
||||||
|
struct list_node stack_neighbour;
|
||||||
/// The actual window correspond to this stack entry. NULL if we didn't know about
|
/// The actual window correspond to this stack entry. NULL if we didn't know about
|
||||||
/// this window (e.g. an InputOnly window, or we haven't handled the window
|
/// this window (e.g. an InputOnly window, or we haven't handled the window
|
||||||
/// creation yet)
|
/// creation yet)
|
||||||
|
@ -124,7 +132,6 @@ struct window_stack_entry {
|
||||||
/// The window id. Might not be unique in the stack, because there might be
|
/// The window id. Might not be unique in the stack, because there might be
|
||||||
/// destroyed window still fading out in the stack.
|
/// destroyed window still fading out in the stack.
|
||||||
xcb_window_t id;
|
xcb_window_t id;
|
||||||
struct list_node stack_neighbour;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,18 +148,30 @@ struct window_stack_entry {
|
||||||
/// Structure representing a top-level window compton manages.
|
/// Structure representing a top-level window compton manages.
|
||||||
typedef struct win win;
|
typedef struct win win;
|
||||||
struct win {
|
struct win {
|
||||||
|
UT_hash_handle hh;
|
||||||
struct list_node stack_neighbour;
|
struct list_node stack_neighbour;
|
||||||
|
/// ID of the top-level frame window.
|
||||||
|
xcb_window_t id;
|
||||||
|
/// Whether the window is destroyed from Xorg's perspective
|
||||||
|
bool destroyed : 1;
|
||||||
|
/// True if we just received CreateNotify, and haven't queried X for any info
|
||||||
|
/// about the window
|
||||||
|
bool is_new : 1;
|
||||||
|
/// True if this window is managed, i.e. this struct is actually a `managed_win`.
|
||||||
|
/// Always false if `is_new` is true.
|
||||||
|
bool managed : 1;
|
||||||
|
};
|
||||||
|
struct managed_win {
|
||||||
|
struct win base;
|
||||||
/// backend data attached to this window. Only available when
|
/// backend data attached to this window. Only available when
|
||||||
/// `state` is not UNMAPPED
|
/// `state` is not UNMAPPED
|
||||||
void *win_image;
|
void *win_image;
|
||||||
void *shadow_image;
|
void *shadow_image;
|
||||||
/// Pointer to the next higher window to paint.
|
/// Pointer to the next higher window to paint.
|
||||||
win *prev_trans;
|
struct managed_win *prev_trans;
|
||||||
// TODO rethink reg_ignore
|
// TODO rethink reg_ignore
|
||||||
|
|
||||||
// Core members
|
// Core members
|
||||||
/// ID of the top-level frame window.
|
|
||||||
xcb_window_t id;
|
|
||||||
/// The "mapped state" of this window, doesn't necessary
|
/// The "mapped state" of this window, doesn't necessary
|
||||||
/// match X mapped state, because of fading.
|
/// match X mapped state, because of fading.
|
||||||
winstate_t state;
|
winstate_t state;
|
||||||
|
@ -299,64 +318,67 @@ struct win {
|
||||||
/// Textures and FBO background blur use.
|
/// Textures and FBO background blur use.
|
||||||
glx_blur_cache_t glx_blur_cache;
|
glx_blur_cache_t glx_blur_cache;
|
||||||
#endif
|
#endif
|
||||||
UT_hash_handle hh;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void win_release_image(backend_t *base, win *w);
|
void win_release_image(backend_t *base, struct managed_win *w);
|
||||||
bool must_use win_bind_image(session_t *ps, win *w);
|
bool must_use win_bind_image(session_t *ps, struct managed_win *w);
|
||||||
|
|
||||||
/// Attempt a rebind of window's images. If that failed, the original images are kept.
|
/// Attempt a rebind of window's images. If that failed, the original images are kept.
|
||||||
bool must_use win_try_rebind_image(session_t *ps, win *w);
|
bool must_use win_try_rebind_image(session_t *ps, struct managed_win *w);
|
||||||
int win_get_name(session_t *ps, win *w);
|
int win_get_name(session_t *ps, struct managed_win *w);
|
||||||
int win_get_role(session_t *ps, win *w);
|
int win_get_role(session_t *ps, struct managed_win *w);
|
||||||
winmode_t attr_pure win_calc_mode(const win *w);
|
winmode_t attr_pure win_calc_mode(const struct managed_win *w);
|
||||||
|
void win_set_shadow_force(session_t *ps, struct managed_win *w, switch_t val);
|
||||||
|
void win_set_fade_force(session_t *ps, struct managed_win *w, switch_t val);
|
||||||
|
void win_set_focused_force(session_t *ps, struct managed_win *w, switch_t val);
|
||||||
|
void win_set_invert_color_force(session_t *ps, struct managed_win *w, switch_t val);
|
||||||
/**
|
/**
|
||||||
* Set real focused state of a window.
|
* Set real focused state of a window.
|
||||||
*/
|
*/
|
||||||
void win_set_focused(session_t *ps, win *w, bool focused);
|
void win_set_focused(session_t *ps, struct managed_win *w, bool focused);
|
||||||
bool attr_pure win_should_fade(session_t *ps, const 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, win *w);
|
void win_update_prop_shadow_raw(session_t *ps, struct managed_win *w);
|
||||||
void win_update_prop_shadow(session_t *ps, win *w);
|
void win_update_prop_shadow(session_t *ps, struct managed_win *w);
|
||||||
void win_set_shadow(session_t *ps, win *w, bool shadow_new);
|
void win_set_shadow(session_t *ps, struct managed_win *w, bool shadow_new);
|
||||||
void win_determine_shadow(session_t *ps, win *w);
|
void win_determine_shadow(session_t *ps, struct managed_win *w);
|
||||||
void win_set_invert_color(session_t *ps, win *w, bool invert_color_new);
|
void win_set_invert_color(session_t *ps, struct managed_win *w, bool invert_color_new);
|
||||||
void win_determine_invert_color(session_t *ps, win *w);
|
void win_determine_invert_color(session_t *ps, struct managed_win *w);
|
||||||
void win_set_blur_background(session_t *ps, win *w, bool blur_background_new);
|
void win_set_blur_background(session_t *ps, struct managed_win *w, bool blur_background_new);
|
||||||
void win_determine_blur_background(session_t *ps, win *w);
|
void win_determine_blur_background(session_t *ps, struct managed_win *w);
|
||||||
void win_on_wtype_change(session_t *ps, win *w);
|
void win_on_wtype_change(session_t *ps, struct managed_win *w);
|
||||||
void win_on_factor_change(session_t *ps, 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.
|
||||||
*/
|
*/
|
||||||
void win_on_win_size_change(session_t *ps, win *w);
|
void win_on_win_size_change(session_t *ps, struct managed_win *w);
|
||||||
void win_update_wintype(session_t *ps, win *w);
|
void win_update_wintype(session_t *ps, struct managed_win *w);
|
||||||
void win_mark_client(session_t *ps, win *w, xcb_window_t client);
|
void win_mark_client(session_t *ps, struct managed_win *w, xcb_window_t client);
|
||||||
void win_unmark_client(session_t *ps, win *w);
|
void win_unmark_client(session_t *ps, struct managed_win *w);
|
||||||
void win_recheck_client(session_t *ps, win *w);
|
void win_recheck_client(session_t *ps, struct managed_win *w);
|
||||||
xcb_window_t win_get_leader_raw(session_t *ps, win *w, int recursions);
|
xcb_window_t win_get_leader_raw(session_t *ps, struct managed_win *w, int recursions);
|
||||||
bool win_get_class(session_t *ps, win *w);
|
bool win_get_class(session_t *ps, struct managed_win *w);
|
||||||
double attr_pure win_calc_opacity_target(session_t *ps, const win *w);
|
double attr_pure win_calc_opacity_target(session_t *ps, const struct managed_win *w);
|
||||||
bool attr_pure win_should_dim(session_t *ps, const win *w);
|
bool attr_pure win_should_dim(session_t *ps, const struct managed_win *w);
|
||||||
void win_update_screen(session_t *, win *);
|
void win_update_screen(session_t *, struct managed_win *);
|
||||||
/// Prepare window for fading because opacity target changed
|
/// Prepare window for fading because opacity target changed
|
||||||
void win_start_fade(session_t *, win **);
|
void win_start_fade(session_t *, struct managed_win **);
|
||||||
/**
|
/**
|
||||||
* Reread opacity property of a window.
|
* Reread opacity property of a window.
|
||||||
*/
|
*/
|
||||||
void win_update_opacity_prop(session_t *ps, win *w);
|
void win_update_opacity_prop(session_t *ps, struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Update leader of a window.
|
* Update leader of a window.
|
||||||
*/
|
*/
|
||||||
void win_update_leader(session_t *ps, win *w);
|
void win_update_leader(session_t *ps, struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Update focused state of a window.
|
* Update focused state of a window.
|
||||||
*/
|
*/
|
||||||
void win_update_focused(session_t *ps, win *w);
|
void win_update_focused(session_t *ps, struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Retrieve the bounding shape of a window.
|
* Retrieve the bounding shape of a window.
|
||||||
*/
|
*/
|
||||||
// XXX was win_border_size
|
// XXX was win_border_size
|
||||||
void win_update_bounding_shape(session_t *ps, win *w);
|
void win_update_bounding_shape(session_t *ps, struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Get a rectangular region in global coordinates a window (and possibly
|
* Get a rectangular region in global coordinates a window (and possibly
|
||||||
* its shadow) occupies.
|
* its shadow) occupies.
|
||||||
|
@ -364,71 +386,109 @@ void win_update_bounding_shape(session_t *ps, win *w);
|
||||||
* Note w->shadow and shadow geometry must be correct before calling this
|
* Note w->shadow and shadow geometry must be correct before calling this
|
||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
void win_extents(const win *w, region_t *res);
|
void win_extents(const struct managed_win *w, region_t *res);
|
||||||
region_t win_extents_by_val(const win *w);
|
region_t win_extents_by_val(const struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Add a window to damaged area.
|
* Add a window to damaged area.
|
||||||
*
|
*
|
||||||
* @param ps current session
|
* @param ps current session
|
||||||
* @param w struct _win element representing the window
|
* @param w struct _win element representing the window
|
||||||
*/
|
*/
|
||||||
void add_damage_from_win(session_t *ps, win *w);
|
void add_damage_from_win(session_t *ps, const struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Get a rectangular region a window occupies, excluding frame and shadow.
|
* Get a rectangular region a window occupies, excluding frame and shadow.
|
||||||
*
|
*
|
||||||
* Return region in global coordinates.
|
* Return region in global coordinates.
|
||||||
*/
|
*/
|
||||||
void win_get_region_noframe_local(const win *w, region_t *);
|
void win_get_region_noframe_local(const struct managed_win *w, region_t *);
|
||||||
region_t win_get_region_noframe_local_by_val(const win *w);
|
region_t win_get_region_noframe_local_by_val(const struct managed_win *w);
|
||||||
|
|
||||||
/// Get the region for the frame of the window
|
/// Get the region for the frame of the window
|
||||||
void win_get_region_frame_local(const win *w, region_t *res);
|
void win_get_region_frame_local(const struct managed_win *w, region_t *res);
|
||||||
/// Get the region for the frame of the window, by value
|
/// Get the region for the frame of the window, by value
|
||||||
region_t win_get_region_frame_local_by_val(const win *w);
|
region_t win_get_region_frame_local_by_val(const struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Retrieve frame extents from a window.
|
* Retrieve frame extents from a window.
|
||||||
*/
|
*/
|
||||||
void win_update_frame_extents(session_t *ps, win *w, xcb_window_t client);
|
void win_update_frame_extents(session_t *ps, struct managed_win *w, xcb_window_t client);
|
||||||
void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev);
|
/// Insert a new window above window with id `below`, if there is no window, add to top
|
||||||
|
/// New window will be in unmapped state
|
||||||
|
struct win *add_win_above(session_t *ps, xcb_window_t id, xcb_window_t below);
|
||||||
|
/// Insert a new win entry at the top of the stack
|
||||||
|
struct win *add_win_top(session_t *ps, xcb_window_t id);
|
||||||
|
/// Query the Xorg for information about window `win`
|
||||||
|
/// `win` pointer might become invalid after this function returns
|
||||||
|
void fill_win(session_t *ps, struct win *win);
|
||||||
/// Unmap or destroy a window
|
/// Unmap or destroy a window
|
||||||
void unmap_win(session_t *ps, win **, bool destroy);
|
void unmap_win(session_t *ps, struct managed_win **, bool destroy);
|
||||||
|
|
||||||
void map_win(session_t *ps, win *w);
|
void map_win(session_t *ps, struct managed_win *w);
|
||||||
void map_win_by_id(session_t *ps, xcb_window_t id);
|
void map_win_by_id(session_t *ps, xcb_window_t id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute fade callback of a window if fading finished.
|
* Execute fade callback of a window if fading finished.
|
||||||
*/
|
*/
|
||||||
void win_check_fade_finished(session_t *ps, win **_w);
|
void win_check_fade_finished(session_t *ps, struct managed_win **_w);
|
||||||
|
|
||||||
// Stop receiving events (except ConfigureNotify, XXX why?) from a window
|
// Stop receiving events (except ConfigureNotify, XXX why?) from a window
|
||||||
void win_ev_stop(session_t *ps, const win *w);
|
void win_ev_stop(session_t *ps, const struct win *w);
|
||||||
|
|
||||||
/// Skip the current in progress fading of window,
|
/// Skip the current in progress fading of window,
|
||||||
/// transition the window straight to its end state
|
/// transition the window straight to its end state
|
||||||
void win_skip_fading(session_t *ps, win **_w);
|
void win_skip_fading(session_t *ps, struct managed_win **_w);
|
||||||
win *find_win(session_t *ps, xcb_window_t id);
|
/**
|
||||||
win *find_toplevel(session_t *ps, xcb_window_t id);
|
* Find a managed window from window id in window linked list of the session.
|
||||||
|
*/
|
||||||
|
struct managed_win *find_managed_win(session_t *ps, xcb_window_t id);
|
||||||
|
struct win *find_win(session_t *ps, xcb_window_t id);
|
||||||
|
struct managed_win *find_toplevel(session_t *ps, xcb_window_t id);
|
||||||
|
/**
|
||||||
|
* Find out the WM frame of a client window by querying X.
|
||||||
|
*
|
||||||
|
* @param ps current session
|
||||||
|
* @param wid window ID
|
||||||
|
* @return struct _win object of the found window, NULL if not found
|
||||||
|
*/
|
||||||
|
struct managed_win *find_toplevel2(session_t *ps, xcb_window_t wid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a window is a fullscreen window.
|
||||||
|
*
|
||||||
|
* It's not using w->border_size for performance measures.
|
||||||
|
*/
|
||||||
|
bool attr_pure win_is_fullscreen(const session_t *ps, const struct managed_win *w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a window will be painted solid.
|
||||||
|
*/
|
||||||
|
bool attr_pure win_is_solid(const session_t *ps, const struct managed_win *w);
|
||||||
|
/**
|
||||||
|
* Check if a window is really focused.
|
||||||
|
*/
|
||||||
|
bool attr_pure win_is_focused_real(const session_t *ps, const struct managed_win *w);
|
||||||
/**
|
/**
|
||||||
* Get the leader of a window.
|
* Get the leader of a window.
|
||||||
*
|
*
|
||||||
* This function updates w->cache_leader if necessary.
|
* This function updates w->cache_leader if necessary.
|
||||||
*/
|
*/
|
||||||
static inline xcb_window_t win_get_leader(session_t *ps, win *w) {
|
static inline xcb_window_t win_get_leader(session_t *ps, struct managed_win *w) {
|
||||||
return win_get_leader_raw(ps, w, 0);
|
return win_get_leader_raw(ps, w, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check if window has ARGB visual
|
/// check if window has ARGB visual
|
||||||
bool attr_pure win_has_alpha(const win *w);
|
bool attr_pure win_has_alpha(const struct managed_win *w);
|
||||||
|
|
||||||
/// check if reg_ignore_valid is true for all windows above us
|
/// check if reg_ignore_valid is true for all windows above us
|
||||||
bool attr_pure win_is_region_ignore_valid(session_t *ps, const win *w);
|
bool attr_pure win_is_region_ignore_valid(session_t *ps, const struct managed_win *w);
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
const struct list_node *w);
|
||||||
|
|
||||||
/// Free all resources in a struct win
|
/// Free all resources in a struct win
|
||||||
void free_win_res(session_t *ps, win *w);
|
void free_win_res(session_t *ps, struct managed_win *w);
|
||||||
|
|
||||||
static inline region_t win_get_bounding_shape_global_by_val(win *w) {
|
static inline region_t win_get_bounding_shape_global_by_val(struct managed_win *w) {
|
||||||
region_t ret;
|
region_t ret;
|
||||||
pixman_region32_init(&ret);
|
pixman_region32_init(&ret);
|
||||||
pixman_region32_copy(&ret, &w->bounding_shape);
|
pixman_region32_copy(&ret, &w->bounding_shape);
|
||||||
|
@ -440,7 +500,7 @@ static inline region_t win_get_bounding_shape_global_by_val(win *w) {
|
||||||
* Calculate the extents of the frame of the given window based on EWMH
|
* Calculate the extents of the frame of the given window based on EWMH
|
||||||
* _NET_FRAME_EXTENTS and the X window border width.
|
* _NET_FRAME_EXTENTS and the X window border width.
|
||||||
*/
|
*/
|
||||||
static inline margin_t attr_pure win_calc_frame_extents(const win *w) {
|
static inline margin_t attr_pure win_calc_frame_extents(const struct managed_win *w) {
|
||||||
margin_t result = w->frame_extents;
|
margin_t result = w->frame_extents;
|
||||||
result.top = max2(result.top, w->g.border_width);
|
result.top = max2(result.top, w->g.border_width);
|
||||||
result.left = max2(result.left, w->g.border_width);
|
result.left = max2(result.left, w->g.border_width);
|
||||||
|
@ -452,7 +512,15 @@ static inline margin_t attr_pure win_calc_frame_extents(const win *w) {
|
||||||
/**
|
/**
|
||||||
* Check whether a window has WM frames.
|
* Check whether a window has WM frames.
|
||||||
*/
|
*/
|
||||||
static inline bool attr_pure win_has_frame(const win *w) {
|
static inline bool attr_pure win_has_frame(const struct managed_win *w) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *win_get_name_if_managed(const struct win *w) {
|
||||||
|
if (!w->managed) {
|
||||||
|
return "(unmanaged)";
|
||||||
|
}
|
||||||
|
auto mw = (struct managed_win *)w;
|
||||||
|
return mw->name;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue