2018-10-04 05:14:51 +08:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Copyright (c) 2011-2013, Christopher Jeffrey
|
|
|
|
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
|
2018-10-21 10:10:12 +08:00
|
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
2019-01-21 05:15:20 +08:00
|
|
|
#include <xcb/xcb.h>
|
|
|
|
#include <xcb/render.h>
|
2018-10-21 10:10:12 +08:00
|
|
|
#include <xcb/damage.h>
|
|
|
|
|
|
|
|
// FIXME shouldn't need this
|
|
|
|
#ifdef CONFIG_OPENGL
|
2019-01-21 05:15:20 +08:00
|
|
|
#include <GL/gl.h>
|
2018-10-21 10:10:12 +08:00
|
|
|
#endif
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
|
|
|
|
#include "x.h"
|
2019-01-19 07:30:44 +08:00
|
|
|
#include "compiler.h"
|
|
|
|
#include "region.h"
|
2018-10-21 10:10:12 +08:00
|
|
|
#include "types.h"
|
|
|
|
#include "c2.h"
|
2018-12-16 05:11:41 +08:00
|
|
|
#include "render.h"
|
2019-01-21 00:53:39 +08:00
|
|
|
#include "utils.h"
|
2018-09-07 02:17:26 +08:00
|
|
|
|
|
|
|
typedef struct session session_t;
|
2018-10-21 10:10:12 +08:00
|
|
|
typedef struct _glx_texture glx_texture_t;
|
|
|
|
|
2018-10-29 07:09:25 +08:00
|
|
|
#ifdef CONFIG_OPENGL
|
2018-10-21 10:10:12 +08:00
|
|
|
// FIXME this type should be in opengl.h
|
|
|
|
// it is very unideal for it to be here
|
|
|
|
typedef struct {
|
|
|
|
/// Framebuffer used for blurring.
|
|
|
|
GLuint fbo;
|
|
|
|
/// Textures used for blurring.
|
|
|
|
GLuint textures[2];
|
|
|
|
/// Width of the textures.
|
|
|
|
int width;
|
|
|
|
/// Height of the textures.
|
|
|
|
int height;
|
|
|
|
} glx_blur_cache_t;
|
2018-10-29 07:09:25 +08:00
|
|
|
#endif
|
2018-10-21 10:10:12 +08:00
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
WINTYPE_UNKNOWN,
|
|
|
|
WINTYPE_DESKTOP,
|
|
|
|
WINTYPE_DOCK,
|
|
|
|
WINTYPE_TOOLBAR,
|
|
|
|
WINTYPE_MENU,
|
|
|
|
WINTYPE_UTILITY,
|
|
|
|
WINTYPE_SPLASH,
|
|
|
|
WINTYPE_DIALOG,
|
|
|
|
WINTYPE_NORMAL,
|
|
|
|
WINTYPE_DROPDOWN_MENU,
|
|
|
|
WINTYPE_POPUP_MENU,
|
|
|
|
WINTYPE_TOOLTIP,
|
|
|
|
WINTYPE_NOTIFY,
|
|
|
|
WINTYPE_COMBO,
|
|
|
|
WINTYPE_DND,
|
|
|
|
NUM_WINTYPES
|
|
|
|
} wintype_t;
|
|
|
|
|
|
|
|
/// Enumeration type of window painting mode.
|
|
|
|
typedef enum {
|
|
|
|
WMODE_TRANS, // The window body is (potentially) transparent
|
|
|
|
WMODE_FRAME_TRANS, // The window body is opaque, but the frame is not
|
|
|
|
WMODE_SOLID, // The window is opaque including the frame
|
|
|
|
} winmode_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* About coordinate systems
|
|
|
|
*
|
|
|
|
* In general, X is the horizontal axis, Y is the vertical axis.
|
|
|
|
* X goes from left to right, Y goes downwards.
|
|
|
|
*
|
|
|
|
* Global: the origin is the top left corner of the Xorg screen.
|
|
|
|
* Local: the origin is the top left corner of the window, including border.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/// Structure representing a top-level window compton manages.
|
2018-09-07 02:17:26 +08:00
|
|
|
typedef struct win win;
|
2018-10-21 10:10:12 +08:00
|
|
|
struct win {
|
2018-10-04 05:46:18 +08:00
|
|
|
/// backend data attached to this window. Only available when
|
|
|
|
/// `state` is not UNMAPPED
|
|
|
|
void *win_data;
|
2018-10-21 10:10:12 +08:00
|
|
|
/// Pointer to the next lower window in window stack.
|
|
|
|
win *next;
|
|
|
|
/// Pointer to the next higher window to paint.
|
|
|
|
win *prev_trans;
|
|
|
|
|
|
|
|
// Core members
|
|
|
|
/// ID of the top-level frame window.
|
2018-12-28 04:45:38 +08:00
|
|
|
xcb_window_t id;
|
2018-10-21 10:10:12 +08:00
|
|
|
/// Window attributes.
|
|
|
|
xcb_get_window_attributes_reply_t a;
|
|
|
|
xcb_get_geometry_reply_t g;
|
|
|
|
#ifdef CONFIG_XINERAMA
|
|
|
|
/// Xinerama screen this window is on.
|
|
|
|
int xinerama_scr;
|
|
|
|
#endif
|
|
|
|
/// Window visual pict format;
|
|
|
|
xcb_render_pictforminfo_t *pictfmt;
|
|
|
|
/// Window painting mode.
|
|
|
|
winmode_t mode;
|
|
|
|
/// Whether the window has been damaged at least once.
|
|
|
|
bool ever_damaged;
|
|
|
|
/// Whether the window was damaged after last paint.
|
|
|
|
bool pixmap_damaged;
|
|
|
|
/// Damage of the window.
|
|
|
|
xcb_damage_damage_t damage;
|
|
|
|
/// Paint info of the window.
|
|
|
|
paint_t paint;
|
|
|
|
|
|
|
|
/// Bounding shape of the window. In local coordinates.
|
|
|
|
/// See above about coordinate systems.
|
|
|
|
region_t bounding_shape;
|
|
|
|
/// Window flags. Definitions above.
|
|
|
|
int_fast16_t flags;
|
|
|
|
/// Whether there's a pending <code>ConfigureNotify</code> happening
|
|
|
|
/// when the window is unmapped.
|
|
|
|
bool need_configure;
|
|
|
|
/// Queued <code>ConfigureNotify</code> when the window is unmapped.
|
|
|
|
xcb_configure_notify_event_t queue_configure;
|
2018-12-22 08:33:40 +08:00
|
|
|
/// The region of screen that will be obscured when windows above is painted,
|
|
|
|
/// in global coordinates.
|
2018-10-21 10:10:12 +08:00
|
|
|
/// We use this to reduce the pixels that needed to be paint when painting
|
|
|
|
/// this window and anything underneath. Depends on window frame
|
|
|
|
/// opacity state, window geometry, window mapped/unmapped state,
|
|
|
|
/// 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.
|
|
|
|
rc_region_t *reg_ignore;
|
|
|
|
/// Whether the reg_ignore of all windows beneath this window are valid
|
|
|
|
bool reg_ignore_valid;
|
|
|
|
/// Cached width/height of the window including border.
|
|
|
|
int widthb, heightb;
|
2019-02-03 03:42:05 +08:00
|
|
|
/// Whether the window is being destroyed. This being true means destroy_win
|
|
|
|
/// is called, but window might still need to be faded out
|
|
|
|
bool destroying;
|
2018-10-21 10:10:12 +08:00
|
|
|
/// Whether the window is bounding-shaped.
|
|
|
|
bool bounding_shaped;
|
|
|
|
/// Whether the window just have rounded corners.
|
|
|
|
bool rounded_corners;
|
|
|
|
/// Whether this window is to be painted.
|
|
|
|
bool to_paint;
|
|
|
|
/// Whether the window is painting excluded.
|
|
|
|
bool paint_excluded;
|
|
|
|
/// Whether the window is unredirect-if-possible excluded.
|
|
|
|
bool unredir_if_possible_excluded;
|
|
|
|
/// Whether this window is in open/close state.
|
|
|
|
bool in_openclose;
|
2018-09-07 02:17:26 +08:00
|
|
|
|
2018-10-21 10:10:12 +08:00
|
|
|
// Client window related members
|
|
|
|
/// ID of the top-level client window of the window.
|
2018-12-28 04:45:38 +08:00
|
|
|
xcb_window_t client_win;
|
2018-10-21 10:10:12 +08:00
|
|
|
/// Type of the window.
|
|
|
|
wintype_t window_type;
|
|
|
|
/// Whether it looks like a WM window. We consider a window WM window if
|
|
|
|
/// it does not have a decedent with WM_STATE and it is not override-
|
|
|
|
/// redirected itself.
|
|
|
|
bool wmwin;
|
|
|
|
/// Leader window ID of the window.
|
2018-12-28 04:45:38 +08:00
|
|
|
xcb_window_t leader;
|
2018-10-21 10:10:12 +08:00
|
|
|
/// Cached topmost window ID of the window.
|
2018-12-28 04:45:38 +08:00
|
|
|
xcb_window_t cache_leader;
|
2018-10-21 10:10:12 +08:00
|
|
|
|
|
|
|
// Focus-related members
|
|
|
|
/// Whether the window is to be considered focused.
|
|
|
|
bool focused;
|
|
|
|
/// Override value of window focus state. Set by D-Bus method calls.
|
|
|
|
switch_t focused_force;
|
|
|
|
|
|
|
|
// Blacklist related members
|
|
|
|
/// Name of the window.
|
|
|
|
char *name;
|
|
|
|
/// Window instance class of the window.
|
|
|
|
char *class_instance;
|
|
|
|
/// Window general class of the window.
|
|
|
|
char *class_general;
|
|
|
|
/// <code>WM_WINDOW_ROLE</code> value of the window.
|
|
|
|
char *role;
|
|
|
|
const c2_lptr_t *cache_sblst;
|
|
|
|
const c2_lptr_t *cache_fblst;
|
|
|
|
const c2_lptr_t *cache_fcblst;
|
|
|
|
const c2_lptr_t *cache_ivclst;
|
|
|
|
const c2_lptr_t *cache_bbblst;
|
|
|
|
const c2_lptr_t *cache_oparule;
|
|
|
|
const c2_lptr_t *cache_pblst;
|
|
|
|
const c2_lptr_t *cache_uipblst;
|
|
|
|
|
|
|
|
// Opacity-related members
|
|
|
|
/// Current window opacity.
|
|
|
|
opacity_t opacity;
|
|
|
|
/// Target window opacity.
|
|
|
|
opacity_t opacity_tgt;
|
|
|
|
/// true if window (or client window, for broken window managers
|
|
|
|
/// not transferring client window's _NET_WM_OPACITY value) has opacity prop
|
|
|
|
bool has_opacity_prop;
|
|
|
|
/// Cached value of opacity window attribute.
|
|
|
|
opacity_t opacity_prop;
|
|
|
|
/// true if opacity is set by some rules
|
|
|
|
bool opacity_is_set;
|
|
|
|
/// Last window opacity value we set.
|
|
|
|
opacity_t opacity_set;
|
|
|
|
|
|
|
|
// Fading-related members
|
|
|
|
/// Do not fade if it's false. Change on window type change.
|
|
|
|
/// Used by fading blacklist in the future.
|
|
|
|
bool fade;
|
|
|
|
/// Fade state on last paint.
|
|
|
|
bool fade_last;
|
|
|
|
/// Override value of window fade state. Set by D-Bus method calls.
|
|
|
|
switch_t fade_force;
|
|
|
|
/// Callback to be called after fading completed.
|
|
|
|
void (*fade_callback) (session_t *ps, win **w);
|
|
|
|
|
|
|
|
// Frame-opacity-related members
|
|
|
|
/// Current window frame opacity. Affected by window opacity.
|
|
|
|
double frame_opacity;
|
|
|
|
/// Frame extents. Acquired from _NET_FRAME_EXTENTS.
|
|
|
|
margin_t frame_extents;
|
|
|
|
|
|
|
|
// Shadow-related members
|
|
|
|
/// Whether a window has shadow. Calculated.
|
|
|
|
bool shadow;
|
|
|
|
/// Shadow state on last paint.
|
|
|
|
bool shadow_last;
|
|
|
|
/// Override value of window shadow state. Set by D-Bus method calls.
|
|
|
|
switch_t shadow_force;
|
|
|
|
/// Opacity of the shadow. Affected by window opacity and frame opacity.
|
|
|
|
double shadow_opacity;
|
|
|
|
/// X offset of shadow. Affected by commandline argument.
|
|
|
|
int shadow_dx;
|
|
|
|
/// Y offset of shadow. Affected by commandline argument.
|
|
|
|
int shadow_dy;
|
|
|
|
/// Width of shadow. Affected by window size and commandline argument.
|
|
|
|
int shadow_width;
|
|
|
|
/// Height of shadow. Affected by window size and commandline argument.
|
|
|
|
int shadow_height;
|
|
|
|
/// Picture to render shadow. Affected by window size.
|
|
|
|
paint_t shadow_paint;
|
|
|
|
/// The value of _COMPTON_SHADOW attribute of the window. Below 0 for
|
|
|
|
/// none.
|
|
|
|
long prop_shadow;
|
|
|
|
|
|
|
|
// Dim-related members
|
|
|
|
/// Whether the window is to be dimmed.
|
|
|
|
bool dim;
|
|
|
|
|
|
|
|
/// Whether to invert window color.
|
|
|
|
bool invert_color;
|
|
|
|
/// Color inversion state on last paint.
|
|
|
|
bool invert_color_last;
|
|
|
|
/// Override value of window color inversion state. Set by D-Bus method
|
|
|
|
/// calls.
|
|
|
|
switch_t invert_color_force;
|
|
|
|
|
|
|
|
/// Whether to blur window background.
|
|
|
|
bool blur_background;
|
|
|
|
/// Background state on last paint.
|
|
|
|
bool blur_background_last;
|
|
|
|
|
|
|
|
#ifdef CONFIG_OPENGL
|
|
|
|
/// Textures and FBO background blur use.
|
|
|
|
glx_blur_cache_t glx_blur_cache;
|
|
|
|
#endif
|
|
|
|
};
|
2018-09-07 02:17:26 +08:00
|
|
|
|
|
|
|
int win_get_name(session_t *ps, win *w);
|
|
|
|
int win_get_role(session_t *ps, win *w);
|
|
|
|
void win_determine_mode(session_t *ps, win *w);
|
|
|
|
/**
|
|
|
|
* Set real focused state of a window.
|
|
|
|
*/
|
|
|
|
void win_set_focused(session_t *ps, win *w, bool focused);
|
|
|
|
void win_determine_fade(session_t *ps, win *w);
|
|
|
|
void win_update_prop_shadow_raw(session_t *ps, win *w);
|
|
|
|
void win_update_prop_shadow(session_t *ps, win *w);
|
|
|
|
void win_set_shadow(session_t *ps, win *w, bool shadow_new);
|
|
|
|
void win_determine_shadow(session_t *ps, win *w);
|
|
|
|
void win_set_invert_color(session_t *ps, win *w, bool invert_color_new);
|
|
|
|
void win_determine_invert_color(session_t *ps, win *w);
|
|
|
|
void win_set_blur_background(session_t *ps, win *w, bool blur_background_new);
|
|
|
|
void win_determine_blur_background(session_t *ps, win *w);
|
|
|
|
void win_on_wtype_change(session_t *ps, win *w);
|
|
|
|
void win_on_factor_change(session_t *ps, win *w);
|
|
|
|
void calc_win_size(session_t *ps, win *w);
|
|
|
|
void calc_shadow_geometry(session_t *ps, win *w);
|
|
|
|
void win_upd_wintype(session_t *ps, win *w);
|
2018-12-28 04:45:38 +08:00
|
|
|
void win_mark_client(session_t *ps, win *w, xcb_window_t client);
|
2018-09-07 02:17:26 +08:00
|
|
|
void win_unmark_client(session_t *ps, win *w);
|
|
|
|
void win_recheck_client(session_t *ps, win *w);
|
2018-12-28 04:45:38 +08:00
|
|
|
xcb_window_t win_get_leader_raw(session_t *ps, win *w, int recursions);
|
2018-09-07 02:17:26 +08:00
|
|
|
bool win_get_class(session_t *ps, win *w);
|
|
|
|
void win_calc_opacity(session_t *ps, win *w);
|
|
|
|
void win_calc_dim(session_t *ps, win *w);
|
|
|
|
/**
|
|
|
|
* Reread opacity property of a window.
|
|
|
|
*/
|
|
|
|
void win_update_opacity_prop(session_t *ps, win *w);
|
|
|
|
/**
|
|
|
|
* Update leader of a window.
|
|
|
|
*/
|
|
|
|
void win_update_leader(session_t *ps, win *w);
|
|
|
|
/**
|
|
|
|
* Update focused state of a window.
|
|
|
|
*/
|
|
|
|
void win_update_focused(session_t *ps, win *w);
|
|
|
|
/**
|
|
|
|
* Retrieve the bounding shape of a window.
|
|
|
|
*/
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
// XXX was win_border_size
|
|
|
|
void win_update_bounding_shape(session_t *ps, win *w);
|
2018-09-07 02:17:26 +08:00
|
|
|
/**
|
2018-12-22 08:33:40 +08:00
|
|
|
* Get a rectangular region in global coordinates a window (and possibly
|
|
|
|
* its shadow) occupies.
|
2018-09-07 02:17:26 +08:00
|
|
|
*
|
|
|
|
* Note w->shadow and shadow geometry must be correct before calling this
|
|
|
|
* function.
|
|
|
|
*/
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
void win_extents(win *w, region_t *res);
|
2018-12-22 08:33:40 +08:00
|
|
|
region_t win_extents_by_val(win *w);
|
2018-09-07 02:17:26 +08:00
|
|
|
/**
|
|
|
|
* Add a window to damaged area.
|
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param w struct _win element representing the window
|
|
|
|
*/
|
|
|
|
void add_damage_from_win(session_t *ps, win *w);
|
|
|
|
/**
|
|
|
|
* Get a rectangular region a window occupies, excluding frame and shadow.
|
2018-10-13 08:17:59 +08:00
|
|
|
*
|
|
|
|
* Return region in global coordinates.
|
2018-09-07 02:17:26 +08:00
|
|
|
*/
|
2018-10-22 05:07:48 +08:00
|
|
|
void win_get_region_noframe_local(win *w, region_t *);
|
2018-12-22 08:33:40 +08:00
|
|
|
region_t win_get_region_noframe_local_by_val(win *w);
|
2018-09-07 02:17:26 +08:00
|
|
|
/**
|
|
|
|
* Retrieve frame extents from a window.
|
|
|
|
*/
|
|
|
|
void
|
2018-12-28 04:45:38 +08:00
|
|
|
win_update_frame_extents(session_t *ps, win *w, xcb_window_t client);
|
|
|
|
bool add_win(session_t *ps, xcb_window_t id, xcb_window_t prev);
|
2018-09-07 02:17:26 +08:00
|
|
|
|
2018-12-16 05:11:41 +08:00
|
|
|
/**
|
|
|
|
* Set fade callback of a window, and possibly execute the previous
|
|
|
|
* callback.
|
|
|
|
*
|
|
|
|
* If a callback can cause rendering result to change, it should call
|
|
|
|
* `queue_redraw`.
|
|
|
|
*
|
|
|
|
* @param exec_callback whether the previous callback is to be executed
|
|
|
|
*/
|
|
|
|
void win_set_fade_callback(session_t *ps, win **_w,
|
|
|
|
void (*callback) (session_t *ps, win **w), bool exec_callback);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute fade callback of a window if fading finished.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
win_check_fade_finished(session_t *ps, win **_w);
|
|
|
|
|
2018-11-04 06:38:18 +08:00
|
|
|
// Stop receiving events (except ConfigureNotify, XXX why?) from a window
|
|
|
|
void win_ev_stop(session_t *ps, win *w);
|
|
|
|
|
2018-09-07 02:17:26 +08:00
|
|
|
/**
|
|
|
|
* Get the leader of a window.
|
|
|
|
*
|
|
|
|
* This function updates w->cache_leader if necessary.
|
|
|
|
*/
|
2018-12-28 04:45:38 +08:00
|
|
|
static inline xcb_window_t
|
2018-09-07 02:17:26 +08:00
|
|
|
win_get_leader(session_t *ps, win *w) {
|
|
|
|
return win_get_leader_raw(ps, w, 0);
|
|
|
|
}
|
2018-09-30 02:07:39 +08:00
|
|
|
|
|
|
|
/// check if window has ARGB visual
|
|
|
|
bool win_has_alpha(win *w);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-30 11:56:00 +08:00
|
|
|
|
|
|
|
/// check if reg_ignore_valid is true for all windows above us
|
|
|
|
bool win_is_region_ignore_valid(session_t *ps, win *w);
|
2018-10-13 08:17:59 +08:00
|
|
|
|
|
|
|
static inline region_t
|
|
|
|
win_get_bounding_shape_global_by_val(win *w) {
|
|
|
|
region_t ret;
|
|
|
|
pixman_region32_init(&ret);
|
|
|
|
pixman_region32_copy(&ret, &w->bounding_shape);
|
|
|
|
pixman_region32_translate(&ret, w->g.x, w->g.y);
|
|
|
|
return ret;
|
|
|
|
}
|
2018-10-21 10:10:12 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate the extents of the frame of the given window based on EWMH
|
|
|
|
* _NET_FRAME_EXTENTS and the X window border width.
|
|
|
|
*/
|
2018-12-20 04:50:02 +08:00
|
|
|
static inline margin_t attr_pure
|
2018-10-22 05:07:48 +08:00
|
|
|
win_calc_frame_extents(const win *w) {
|
2018-10-21 10:10:12 +08:00
|
|
|
margin_t result = w->frame_extents;
|
|
|
|
result.top = max_i(result.top, w->g.border_width);
|
|
|
|
result.left = max_i(result.left, w->g.border_width);
|
|
|
|
result.bottom = max_i(result.bottom, w->g.border_width);
|
|
|
|
result.right = max_i(result.right, w->g.border_width);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether a window has WM frames.
|
|
|
|
*/
|
2018-12-20 04:50:02 +08:00
|
|
|
static inline bool attr_pure
|
2018-10-21 10:10:12 +08:00
|
|
|
win_has_frame(const win *w) {
|
|
|
|
return w->g.border_width
|
|
|
|
|| w->frame_extents.top || w->frame_extents.left
|
|
|
|
|| w->frame_extents.right || w->frame_extents.bottom;
|
|
|
|
}
|