From b0766e09b68914654fe3d4689ce21c9fc914145e Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Oct 2012 03:04:19 -0500 Subject: [PATCH 1/6] v0.0.1 --- src/compton.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compton.c b/src/compton.c index c5243c1..5760528 100755 --- a/src/compton.c +++ b/src/compton.c @@ -3151,7 +3151,7 @@ ev_handle(XEvent *ev) { static void usage(void) { fputs( - "compton (development version)\n" + "compton (v0.0.1)\n" "usage: compton [options]\n" "Options:\n" "\n" @@ -3320,7 +3320,7 @@ register_cm(Bool want_glxct) { opts.vsync = VSYNC_NONE; } #endif - + if (!reg_win) reg_win = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, None, None); @@ -4070,7 +4070,7 @@ vsync_drm_wait(void) { "unimplemented in this drmver?\n"); return ret; - + } #endif @@ -4095,7 +4095,7 @@ vsync_opengl_init(void) { "Failed to get glXWait/GetVideoSyncSGI function.\n"); return False; } - + return True; #else fprintf(stderr, "Program not compiled with OpenGL VSync support.\n"); From 7ace6ca68da9d126bf96dc82542a84db96b18325 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Oct 2012 06:35:02 -0500 Subject: [PATCH 2/6] revert to c7ca345 --- .gitignore | 25 +- CMakeLists.txt | 160 ------- CPackConfig.cmake | 40 -- Makefile | 50 +- README.md | 3 - compton.sample.conf | 5 +- desc.txt | 1 - src/compton.c | 1064 +++++++++---------------------------------- src/compton.h | 198 +------- 9 files changed, 244 insertions(+), 1302 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 CPackConfig.cmake delete mode 100644 desc.txt mode change 100755 => 100644 src/compton.c diff --git a/.gitignore b/.gitignore index cb2c71d..90d2c8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -# Build files .deps +Makefile +Makefile.in aclocal.m4 autom4te.cache config.h @@ -13,26 +14,14 @@ missing stamp-h1 compton *.o -build/ - -# CMake files -compton-*.deb -compton-*.rpm -compton-*.tar.bz2 -release/ -_CPack_Packages/ -CMakeCache.txt -CMakeFiles/ -*.cmake -install_manifest.txt - +*~ +core # Vim files .*.sw[a-z] -*~ -# Misc files -core +# oprofile files oprofile_data + +# clang files compton.plist -callgrind.out.* diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 838fa55..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,160 +0,0 @@ -project(compton) -cmake_minimum_required(VERSION 2.8) - -set(CPACK_PACKAGE_VERSION_MAJOR "0") -set(CPACK_PACKAGE_VERSION_MINOR "0") -set(CPACK_PACKAGE_VERSION_PATCH "0") - -set(compton_SRCS src/compton.c) -add_executable(compton ${compton_SRCS}) - -set(CMAKE_C_FLAGS_DEBUG "-ggdb") -set(CMAKE_C_FLAGS_RELEASE "-O2 -march=native") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -march=native -ggdb") - -add_definitions("-Wall" "-std=c99") - -# == Options == - -option(CONFIG_REGEX_PCRE "Enable PCRE regular expression support for blacklist entries (requires libpcre)" ON) -if (CONFIG_REGEX_PCRE) - add_definitions("-DCONFIG_REGEX_PCRE") -endif () - -option(CONFIG_REGEX_PCRE_JIT "Use JIT support of libpcre)" ON) -if (CONFIG_REGEX_PCRE_JIT) - add_definitions("-DCONFIG_REGEX_PCRE_JIT") -endif () - -option(CONFIG_LIBCONFIG "Enable configuration file parsing using libconfig" ON) -if (CONFIG_LIBCONFIG) - add_definitions("-DCONFIG_LIBCONFIG") -endif () - -option(CONFIG_VSYNC_DRM "Enable DRM VSync support" ON) -if (CONFIG_VSYNC_DRM) - add_definitions("-DCONFIG_VSYNC_DRM") -endif () - -option(CONFIG_VSYNC_OPENGL "Enable OpenGL VSync support" ON) -if (CONFIG_VSYNC_OPENGL) - add_definitions("-DCONFIG_VSYNC_OPENGL") -endif () - -# == Find libraries == - -target_link_libraries(compton "-lm" "-lrt") - -if (CONFIG_VSYNC_OPENGL) - target_link_libraries(compton "-lGL") -endif () - -include(FindPkgConfig) - -# --- Find X11 libs --- -set(X11_FIND_REQUIRED 1) -include(FindX11) - -macro(X11LIB_CHK lib) - if (NOT X11_${lib}_FOUND) - message(FATAL_ERROR "Could not find lib${lib}.") - endif () - target_link_libraries(compton "${X11_${lib}_LIB}") -endmacro () - -X11LIB_CHK(Xcomposite) -X11LIB_CHK(Xdamage) -X11LIB_CHK(Xext) -X11LIB_CHK(Xfixes) -X11LIB_CHK(Xrender) -X11LIB_CHK(Xrandr) - -# --- Find libpcre --- -if (CONFIG_REGEX_PCRE) - pkg_check_modules(LIBPCRE REQUIRED libpcre>=8.12) - target_link_libraries(compton "${LIBPCRE_LDFLAGS}") -endif () - -# --- Find libconfig --- -if (CONFIG_LIBCONFIG) - pkg_check_modules(LIBCONFIG REQUIRED libconfig>=1.3.2) - target_link_libraries(compton "${LIBCONFIG_LDFLAGS}") - if (LIBCONFIG_VERSION VERSION_LESS 1.4) - add_definitions("-DCONFIG_LIBCONFIG_LEGACY") - message(STATUS "libconfig-1.3* detected. Enable legacy mode.") - endif () -endif () - -# == Install == -include(GNUInstallDirs) - -install(TARGETS compton - DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT prog) -install(FILES "${PROJECT_SOURCE_DIR}/bin/compton-trans" - DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT prog) -install(FILES - "${PROJECT_SOURCE_DIR}/man/compton.1" - "${PROJECT_SOURCE_DIR}/man/compton-trans.1" - DESTINATION "${CMAKE_INSTALL_MANDIR}" COMPONENT doc) -install(FILES - "${PROJECT_SOURCE_DIR}/README.md" - "${PROJECT_SOURCE_DIR}/LICENSE" - DESTINATION "${CMAKE_INSTALL_DOCDIR}" COMPONENT doc) - -# == CPack == - -if (NOT CPACK_SYSTEM_NAME) - set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_PROCESSOR}") -endif () - -set(CPACK_PACKAGE_DESCRIPTION "A lightweight X compositing window manager, fork of xcompmgr-dana.") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A lightweight X compositing window manager") -set(CPACK_PACKAGE_CONTACT "nobody ") -set(CPACK_PACKAGE_DIRECTORY "${CMAKE_SOURCE_DIR}/release") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/desc.txt") - -# --- Package config --- -set(CPACK_GENERATOR "TBZ2" "DEB" "RPM") -set(CPACK_MONOLITHIC_INSTALL 1) -set(CPACK_STRIP_FILES 1) -set(CPACK_RESOURCE_FILE_LICENSE "LICENSE") -set(CPACK_RESOURCE_FILE_README "README.md") - -# --- Source package config --- -set(CPACK_SOURCE_GENERATOR "TBZ2" "DEB" "RPM") -set(CPACK_SOURCE_IGNORE_FILES - "/\\\\." - "\\\\.bak$" - "\\\\.o$" - "\\\\~$" - "\\\\.plist$" - "/compton$" - # Generated package files - "\\\\.tar\\\\.gz$" - "\\\\.tar\\\\.bz2$" - "\\\\.deb$" - "\\\\.rpm$" - "compton-.*\\\\.sh$" - # CMake files - "/Makefile$" - "/CMakeFiles/" - "\\\\.cmake$" - "CMakeCache\\\\.txt$" - "/build/" - "/release/" - "\\\\.diff$" - "/oprofile_data/" - "/install_manifest\\\\.txt$" -) - -# --- DEB package config --- -set(CPACK_DEBIAN_PACKAGE_SECTION "x11") -# The dependencies are unreliable, just an example here -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libx11-6, libxext6, libxcomposite1, libxrender1, libxdamage1, libxfixes3, libpcre3, libconfig8") - -# --- RPM package config --- -set(CPACK_RPM_PACKAGE_LICENSE "unknown") -# The dependencies are unreliable, just an example here -set(CPACK_RPM_PACKAGE_REQUIRES "libx11, libxext, libxcomposite, libxrender, libxdamage, libxfixes, libpcre, libconfig") - -include(CPack) diff --git a/CPackConfig.cmake b/CPackConfig.cmake deleted file mode 100644 index 87be000..0000000 --- a/CPackConfig.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# == Environment == -if (NOT CPACK_SYSTEM_NAME) - set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_PROCESSOR}") - if (CPACK_SYSTEM_NAME STREQUAL "x86_64") - set(CPACK_SYSTEM_NAME "amd64") - endif () -endif () - -# == Basic information == -set(CPACK_PACKAGE_NAME "compton") -set(CPACK_PACKAGE_VENDOR "chjj") -set(CPACK_PACKAGE_VERSION_MAJOR "0") -set(CPACK_PACKAGE_VERSION_MINOR "0") -set(CPACK_PACKAGE_VERSION_PATCH "0") -set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") -set(CPACK_PACKAGE_DESCRIPTION "A lightweight X compositing window manager, fork of xcompmgr-dana.") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A lightweight X compositing window manager") -set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}") -set(CPACK_PACKAGE_CONTACT "nobody ") -set(CPACK_INSTALL_COMMANDS "env PREFIX=build make install") - -# == Package config == -set(CPACK_INSTALLED_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/build" "usr") -set(CPACK_GENERATOR "TBZ2" "DEB" "RPM") -set(CPACK_RESOURCE_FILE_LICENSE "LICENSE") -set(CPACK_RESOURCE_FILE_README "README.md") -set(CPACK_STRIP_FILES 1) - -# == DEB package config == -set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_SYSTEM_NAME}") -set(CPACK_DEBIAN_PACKAGE_SECTION "x11") -# The dependencies are unreliable, just an example here -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libx11-6, libxext6, libxcomposite1, libxrender1, libxdamage1, libxfixes3, libpcre3, libconfig8") - -# == RPM package config == -# The dependencies are unreliable, just an example here -set(CPACK_RPM_PACKAGE_REQUIRES "libx11, libxext, libxcomposite, libxrender, libxdamage, libxfixes, libpcre, libconfig") - -# == Source package config == -set(CPACK_SOURCE_GENERATOR "TBZ2 DEB RPM") diff --git a/Makefile b/Makefile index 6dbdf36..47be594 100644 --- a/Makefile +++ b/Makefile @@ -4,48 +4,20 @@ PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man/man1 -PACKAGES = x11 xcomposite xfixes xdamage xrender xext xrandr -LIBS = -lm -lrt -INCS = - -# Parse configuration flags -CFG = - -ifeq "$(NO_LIBCONFIG)" "" - CFG += -DCONFIG_LIBCONFIG - PACKAGES += libconfig - - # libconfig-1.3* does not define LIBCONFIG_VER* macros, so we use - # pkg-config to determine its version here - CFG += $(shell pkg-config --atleast-version=1.4 libconfig || echo '-DCONFIG_LIBCONFIG_LEGACY') -endif - -ifeq "$(NO_REGEX_PCRE)" "" - CFG += -DCONFIG_REGEX_PCRE - LIBS += $(shell pcre-config --libs) - INCS += $(shell pcre-config --cflags) - ifeq "$(NO_REGEX_PCRE_JIT)" "" - CFG += -DCONFIG_REGEX_PCRE_JIT - endif -endif - -ifeq "$(NO_VSYNC_DRM)" "" - CFG += -DCONFIG_VSYNC_DRM -endif - -ifeq "$(NO_VSYNC_OPENGL)" "" - CFG += -DCONFIG_VSYNC_OPENGL - LIBS += -lGL -endif - -CFLAGS ?= -DNDEBUG -CFLAGS += $(CFG) - -LIBS += $(shell pkg-config --libs $(PACKAGES)) -INCS += $(shell pkg-config --cflags $(PACKAGES)) +PACKAGES = x11 xcomposite xfixes xdamage xrender xext libconfig +LIBS = $(shell pkg-config --libs $(PACKAGES)) -lm +LIBS += $(shell pcre-config --libs) +INCS = $(shell pkg-config --cflags $(PACKAGES)) +INCS += $(shell pcre-config --cflags) CFLAGS += -Wall -std=c99 OBJS = compton.o +CFG ?= -DCONFIG_LIBCONFIG -DCONFIG_REGEX_PCRE -DCONFIG_REGEX_PCRE_JIT +# libconfig-1.3* does not define LIBCONFIG_VER* macros, so we use pkg-config +# to determine its version here +CFG += $(shell pkg-config --atleast-version=1.4 libconfig || echo '-DCONFIG_LIBCONFIG_LEGACY') +CFLAGS += $(CFG) + %.o: src/%.c src/%.h $(CC) $(CFLAGS) $(INCS) -c src/$*.c diff --git a/README.md b/README.md index f6dbd52..d3dfc5c 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,6 @@ __R__ for runtime * libxfixes (B,R) * libXext (B,R) * libxrender (B,R) -* libXrandr (B,R) * pkg-config (B) * make (B) * xproto / x11proto (B) @@ -53,8 +52,6 @@ __R__ for runtime * xprop,xwininfo / x11-utils (R) * libpcre (B,R) (Will probably be made optional soon) * libconfig (B,R) (Will probably be made optional soon) -* libdrm (B) (Will probably be made optional soon) -* libGL (B,R) (Will probably be made optional soon) To build, make sure you have the above dependencies: diff --git a/compton.sample.conf b/compton.sample.conf index 6ef97be..857c914 100644 --- a/compton.sample.conf +++ b/compton.sample.conf @@ -18,8 +18,7 @@ shadow-ignore-shaped = true; menu-opacity = 0.8; inactive-opacity = 0.8; frame-opacity = 0.7; -inactive-opacity-override = false; -alpha-step = 0.06; +inactive-opacity-override = true; # Fading fading = true; @@ -32,8 +31,6 @@ fade-out-step = 0.03; mark-wmwin-focused = true; mark-ovredir-focused = true; detect-rounded-corners = true; -detect-client-opacity = false; -refresh-rate = 0; # Window type settings wintypes: diff --git a/desc.txt b/desc.txt deleted file mode 100644 index eadc037..0000000 --- a/desc.txt +++ /dev/null @@ -1 +0,0 @@ -Compton is a X compositing window manager, fork of xcompmgr-dana. diff --git a/src/compton.c b/src/compton.c old mode 100755 new mode 100644 index 5760528..bb9d7bb --- a/src/compton.c +++ b/src/compton.c @@ -35,7 +35,7 @@ const char *WINTYPES[NUM_WINTYPES] = { struct timeval time_start = { 0, 0 }; win *list; -Display *dpy = NULL; +Display *dpy; int scr; Window root; @@ -47,67 +47,25 @@ Picture cshadow_picture; Picture dim_picture = 0; Picture root_tile; XserverRegion all_damage; +#if HAS_NAME_WINDOW_PIXMAP Bool has_name_pixmap; +#endif int root_height, root_width; - -/// Pregenerated alpha pictures. -Picture *alpha_picts = NULL; /// Whether the program is idling. I.e. no fading, no potential window /// changes. Bool idling; -/// Whether all reg_ignore of windows should expire in this paint. -Bool reg_ignore_expire = False; -/// Window ID of the window we register as a symbol. -Window reg_win = 0; - -/// Currently used refresh rate. Used for Software VSync. -short refresh_rate = 0; -/// Interval between refresh in nanoseconds. Used for Software VSync. -unsigned long refresh_intv = 0; -/// Nanosecond-level offset of the first painting. -/// Used for Software VSync. -long paint_tm_offset = 0; - -#ifdef CONFIG_VSYNC_DRM -/// File descriptor of DRI device file. Used for DRM VSync. -int drm_fd = 0; -#endif - -#ifdef CONFIG_VSYNC_OPENGL -/// GLX context. -GLXContext glx_context; - -/// Pointer to glXGetVideoSyncSGI function. Used by OpenGL VSync. -f_GetVideoSync glx_get_video_sync = NULL; - -/// Pointer to glXWaitVideoSyncSGI function. Used by OpenGL VSync. -f_WaitVideoSync glx_wait_video_sync = NULL; -#endif /* errors */ ignore *ignore_head = NULL, **ignore_tail = &ignore_head; int xfixes_event, xfixes_error; int damage_event, damage_error; int composite_event, composite_error; -int render_event, render_error; -int composite_opcode; - /// Whether X Shape extension exists. -Bool shape_exists = False; +Bool shape_exists = True; /// Event base number and error base number for X Shape extension. int shape_event, shape_error; - -/// Whether X RandR extension exists. -Bool randr_exists = False; -/// Event base number and error base number for X RandR extension. -int randr_event, randr_error; - -#ifdef CONFIG_VSYNC_OPENGL -/// Whether X GLX extension exists. -Bool glx_exists = False; -/// Event base number and error base number for X GLX extension. -int glx_event, glx_error; -#endif +int render_event, render_error; +int composite_opcode; /* shadows */ conv *gaussian_map; @@ -137,7 +95,6 @@ Atom client_atom; Atom name_atom; Atom name_ewmh_atom; Atom class_atom; -Atom transient_atom; Atom win_type_atom; Atom win_type[NUM_WINTYPES]; @@ -161,9 +118,6 @@ static options_t opts = { .synchronize = False, .detect_rounded_corners = False, - .refresh_rate = 0, - .vsync = VSYNC_NONE, - .wintype_shadow = { False }, .shadow_red = 0.0, .shadow_green = 0.0, @@ -187,9 +141,7 @@ static options_t opts = { .inactive_opacity = 0, .inactive_opacity_override = False, .frame_opacity = 0.0, - .detect_client_opacity = False, .inactive_dim = 0.0, - .alpha_step = 0.03, .track_focus = False, .track_wdata = False, @@ -208,7 +160,7 @@ unsigned long fade_time = 0; * passed since the epoch. */ static unsigned long -get_time_ms() { +get_time_in_milliseconds() { struct timeval tv; gettimeofday(&tv, NULL); @@ -223,7 +175,7 @@ get_time_ms() { */ static int fade_timeout(void) { - int diff = opts.fade_delta - get_time_ms() + fade_time; + int diff = opts.fade_delta - get_time_in_milliseconds() + fade_time; if (diff < 0) diff = 0; @@ -989,8 +941,7 @@ determine_evmask(Display *dpy, Window wid, win_evmode_t mode) { } if (WIN_EVMODE_CLIENT == mode || find_toplevel(dpy, wid)) { - if (opts.frame_opacity || opts.track_wdata - || opts.detect_client_opacity) + if (opts.frame_opacity || opts.track_wdata) evmask |= PropertyChangeMask; } @@ -1160,36 +1111,6 @@ paint_root(Display *dpy) { root_width, root_height); } -/** - * Get a rectangular region a window occupies, excluding shadow. - */ -static XserverRegion -win_get_region(Display *dpy, win *w) { - XRectangle r; - - r.x = w->a.x; - r.y = w->a.y; - r.width = w->widthb; - r.height = w->heightb; - - return XFixesCreateRegion(dpy, &r, 1); -} - -/** - * Get a rectangular region a window occupies, excluding frame and shadow. - */ -static XserverRegion -win_get_region_noframe(Display *dpy, win *w) { - XRectangle r; - - r.x = w->a.x + w->left_width; - r.y = w->a.y + w->top_width; - r.width = w->a.width; - r.height = w->a.height; - - return XFixesCreateRegion(dpy, &r, 1); -} - /** * Get a rectangular region a window (and possibly its shadow) occupies. * @@ -1315,38 +1236,23 @@ get_frame_extents(Display *dpy, win *w, Window client) { } } -static inline Picture -get_alpha_pict_d(double o) { - assert((lround(normalize_d(o) / opts.alpha_step)) <= lround(1.0 / opts.alpha_step)); - return alpha_picts[lround(normalize_d(o) / opts.alpha_step)]; -} - -static inline Picture -get_alpha_pict_o(opacity_t o) { - return get_alpha_pict_d((double) o / OPAQUE); -} - static win * paint_preprocess(Display *dpy, win *list) { win *w; win *t = NULL, *next = NULL; + // Sounds like the timeout in poll() frequently does not work + // accurately, asking it to wait to 20ms, and often it would wait for + // 19ms, so the step value has to be rounded. + unsigned steps = roundl((double) (get_time_in_milliseconds() - fade_time) / opts.fade_delta); - // Fading step calculation - unsigned steps = (sub_unslong(get_time_ms(), fade_time) - + FADE_DELTA_TOLERANCE * opts.fade_delta) / opts.fade_delta; - fade_time += steps * opts.fade_delta; - - XserverRegion last_reg_ignore = None; + // Reset fade_time + fade_time = get_time_in_milliseconds(); for (w = list; w; w = next) { // In case calling the fade callback function destroys this window next = w->next; opacity_t opacity_old = w->opacity; - // Destroy reg_ignore on all windows if they should expire - if (reg_ignore_expire) - free_region(dpy, &w->reg_ignore); - #if CAN_DO_USABLE if (!w->usable) continue; #endif @@ -1368,10 +1274,7 @@ paint_preprocess(Display *dpy, win *list) { add_damage_win(dpy, w); } - w->alpha_pict = get_alpha_pict_o(w->opacity); - - // End the game if we are using the 0 opacity alpha_pict - if (w->alpha_pict == alpha_picts[0]) { + if (!w->opacity) { check_fade_fin(dpy, w); continue; } @@ -1382,11 +1285,13 @@ paint_preprocess(Display *dpy, win *list) { XRenderPictFormat *format; Drawable draw = w->id; +#if HAS_NAME_WINDOW_PIXMAP if (has_name_pixmap && !w->pixmap) { set_ignore(dpy, NextRequest(dpy)); w->pixmap = XCompositeNameWindowPixmap(dpy, w->id); } if (w->pixmap) draw = w->pixmap; +#endif format = XRenderFindVisualFormat(dpy, w->a.visual); pa.subwindow_mode = IncludeInferiors; @@ -1407,22 +1312,30 @@ paint_preprocess(Display *dpy, win *list) { add_damage_win(dpy, w); } - // Calculate frame_opacity - { - double frame_opacity_old = w->frame_opacity; - - if (opts.frame_opacity && 1.0 != opts.frame_opacity - && w->top_width) - w->frame_opacity = get_opacity_percent(dpy, w) * - opts.frame_opacity; - else - w->frame_opacity = 0.0; - - if ((0.0 == frame_opacity_old) != (0.0 == w->frame_opacity)) - reg_ignore_expire = True; + // Rebuild alpha_pict only if necessary + if (OPAQUE != w->opacity + && (!w->alpha_pict || w->opacity != w->opacity_cur)) { + free_picture(dpy, &w->alpha_pict); + w->alpha_pict = solid_picture( + dpy, False, get_opacity_percent(dpy, w), 0, 0, 0); + w->opacity_cur = w->opacity; } - w->frame_alpha_pict = get_alpha_pict_d(w->frame_opacity); + // Calculate frame_opacity + if (opts.frame_opacity && 1.0 != opts.frame_opacity && w->top_width) + w->frame_opacity = get_opacity_percent(dpy, w) * opts.frame_opacity; + else + w->frame_opacity = 0.0; + + // Rebuild frame_alpha_pict only if necessary + if (w->frame_opacity + && (!w->frame_alpha_pict + || w->frame_opacity != w->frame_opacity_cur)) { + free_picture(dpy, &w->frame_alpha_pict); + w->frame_alpha_pict = solid_picture( + dpy, False, w->frame_opacity, 0, 0, 0); + w->frame_opacity_cur = w->frame_opacity; + } // Calculate shadow opacity if (w->frame_opacity) @@ -1439,36 +1352,16 @@ paint_preprocess(Display *dpy, win *list) { w->widthb, w->heightb); } - w->shadow_alpha_pict = get_alpha_pict_d(w->shadow_opacity); - - // Generate ignore region for painting to reduce GPU load - if (reg_ignore_expire) { - free_region(dpy, &w->reg_ignore); - - // If the window is solid, we add the window region to the - // ignored region - if (WINDOW_SOLID == w->mode) { - if (!w->frame_opacity) - w->reg_ignore = win_get_region(dpy, w); - else - w->reg_ignore = win_get_region_noframe(dpy, w); - - XFixesIntersectRegion(dpy, w->reg_ignore, w->reg_ignore, - w->border_size); - - if (last_reg_ignore) - XFixesUnionRegion(dpy, w->reg_ignore, w->reg_ignore, - last_reg_ignore); - } - // Otherwise we copy the last region over - else if (last_reg_ignore) - w->reg_ignore = copy_region(dpy, last_reg_ignore); - else - w->reg_ignore = None; + // Rebuild shadow_alpha_pict if necessary + if (w->shadow + && (!w->shadow_alpha_pict + || w->shadow_opacity != w->shadow_opacity_cur)) { + free_picture(dpy, &w->shadow_alpha_pict); + w->shadow_alpha_pict = solid_picture( + dpy, False, w->shadow_opacity, 0, 0, 0); + w->shadow_opacity_cur = w->shadow_opacity; } - last_reg_ignore = w->reg_ignore; - // Reset flags w->flags = 0; @@ -1479,82 +1372,13 @@ paint_preprocess(Display *dpy, win *list) { return t; } -/** - * Paint the shadow of a window. - */ -static inline void -win_paint_shadow(Display *dpy, win *w, Picture root_buffer) { - XRenderComposite( - dpy, PictOpOver, w->shadow_pict, w->shadow_alpha_pict, - root_buffer, 0, 0, 0, 0, - w->a.x + w->shadow_dx, w->a.y + w->shadow_dy, - w->shadow_width, w->shadow_height); -} - -/** - * Paint a window itself and dim it if asked. - */ -static inline void -win_paint_win(Display *dpy, win *w, Picture root_buffer) { - int x = w->a.x; - int y = w->a.y; - int wid = w->widthb; - int hei = w->heightb; - - Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict); - int op = (w->mode == WINDOW_SOLID ? PictOpSrc: PictOpOver); - - if (!w->frame_opacity) { - XRenderComposite(dpy, op, w->picture, alpha_mask, - root_buffer, 0, 0, 0, 0, x, y, wid, hei); - } - else { - unsigned int t = w->top_width; - unsigned int l = w->left_width; - unsigned int b = w->bottom_width; - unsigned int r = w->right_width; - - // top - XRenderComposite(dpy, PictOpOver, w->picture, w->frame_alpha_pict, - root_buffer, 0, 0, 0, 0, x, y, wid, t); - - // left - XRenderComposite(dpy, PictOpOver, w->picture, w->frame_alpha_pict, - root_buffer, 0, t, 0, t, x, y + t, l, hei - t); - - // bottom - XRenderComposite(dpy, PictOpOver, w->picture, w->frame_alpha_pict, - root_buffer, l, hei - b, l, hei - b, x + l, y + hei - b, wid - l - r, b); - - // right - XRenderComposite(dpy, PictOpOver, w->picture, w->frame_alpha_pict, - root_buffer, wid - r, t, wid - r, t, x + wid - r, y + t, r, hei - t); - - // body - XRenderComposite(dpy, op, w->picture, alpha_mask, root_buffer, - l, t, l, t, x + l, y + t, wid - l - r, hei - t - b); - - } - - // Dimming the window if needed - if (w->dim) { - XRenderComposite(dpy, PictOpOver, dim_picture, None, - root_buffer, 0, 0, 0, 0, x, y, wid, hei); - } -} - static void paint_all(Display *dpy, XserverRegion region, win *t) { win *w; - XserverRegion reg_paint = None, reg_tmp = None, reg_tmp2 = None; if (!region) { region = get_screen_region(dpy); } - else { - // Remove the damaged area out of screen - XFixesIntersectRegion(dpy, region, region, get_screen_region(dpy)); - } #ifdef MONITOR_REPAINT root_buffer = root_picture; @@ -1581,86 +1405,97 @@ paint_all(Display *dpy, XserverRegion region, win *t) { root_width, root_height); #endif + paint_root(dpy); + #ifdef DEBUG_REPAINT - print_timestamp(); printf("paint:"); #endif - if (t && t->reg_ignore) { - // Calculate the region upon which the root window is to be painted - // based on the ignore region of the lowest window, if available - reg_paint = reg_tmp = XFixesCreateRegion(dpy, NULL, 0); - XFixesSubtractRegion(dpy, reg_paint, region, t->reg_ignore); - } - else { - reg_paint = region; - } - - XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, reg_paint); - - paint_root(dpy); - - // Create temporary regions for use during painting - if (!reg_tmp) - reg_tmp = XFixesCreateRegion(dpy, NULL, 0); - reg_tmp2 = XFixesCreateRegion(dpy, NULL, 0); - for (w = t; w; w = w->prev_trans) { + int x, y, wid, hei; + +#if HAS_NAME_WINDOW_PIXMAP + x = w->a.x; + y = w->a.y; + wid = w->widthb; + hei = w->heightb; +#else + x = w->a.x + w->a.border_width; + y = w->a.y + w->a.border_width; + wid = w->a.width; + hei = w->a.height; +#endif + #ifdef DEBUG_REPAINT printf(" %#010lx", w->id); #endif + // Allow shadow to be painted anywhere in the damaged region + XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region); + // Painting shadow if (w->shadow) { - // Shadow is to be painted based on the ignore region of current - // window - if (w->reg_ignore) { - if (w == t) { - // If it's the first cycle and reg_tmp2 is not ready, calculate - // the paint region here - reg_paint = reg_tmp; - XFixesSubtractRegion(dpy, reg_paint, region, w->reg_ignore); - } - else { - // Otherwise, used the cached region during last cycle - reg_paint = reg_tmp2; - } - XFixesIntersectRegion(dpy, reg_paint, reg_paint, w->extents); - } - else { - reg_paint = region; - } - - // Detect if the region is empty before painting - if (region == reg_paint || !is_region_empty(dpy, reg_paint)) { - XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, reg_paint); - - win_paint_shadow(dpy, w, root_buffer); - } + XRenderComposite( + dpy, PictOpOver, w->shadow_pict, w->shadow_alpha_pict, + root_buffer, 0, 0, 0, 0, + w->a.x + w->shadow_dx, w->a.y + w->shadow_dy, + w->shadow_width, w->shadow_height); } - // Calculate the region based on the reg_ignore of the next (higher) - // window and the bounding region - reg_paint = reg_tmp; - if (w->prev_trans && w->prev_trans->reg_ignore) { - XFixesSubtractRegion(dpy, reg_paint, region, - w->prev_trans->reg_ignore); - // Copy the subtracted region to be used for shadow painting in next - // cycle - XFixesCopyRegion(dpy, reg_tmp2, reg_paint); - XFixesIntersectRegion(dpy, reg_paint, reg_paint, w->border_size); + // The window only could be painted in its bounding region + XserverRegion paint_reg = XFixesCreateRegion(dpy, NULL, 0); + XFixesIntersectRegion(dpy, paint_reg, region, w->border_size); + XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, paint_reg); + + Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict); + int op = (w->mode == WINDOW_SOLID ? PictOpSrc: PictOpOver); + + // Painting the window + if (!w->frame_opacity) { + XRenderComposite(dpy, op, w->picture, alpha_mask, + root_buffer, 0, 0, 0, 0, x, y, wid, hei); } else { - XFixesIntersectRegion(dpy, reg_paint, region, w->border_size); + unsigned int t = w->top_width; + unsigned int l = w->left_width; + unsigned int b = w->bottom_width; + unsigned int r = w->right_width; + + /* top */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + 0, 0, 0, 0, x, y, wid, t); + + /* left */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + 0, t, 0, t, x, y + t, l, hei - t); + + /* bottom */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + l, hei - b, l, hei - b, x + l, y + hei - b, wid - l - r, b); + + /* right */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + wid - r, t, wid - r, t, x + wid - r, y + t, r, hei - t); + + /* body */ + XRenderComposite( + dpy, op, w->picture, alpha_mask, root_buffer, + l, t, l, t, x + l, y + t, wid - l - r, hei - t - b); + } - if (!is_region_empty(dpy, reg_paint)) { - XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, reg_paint); - - // Painting the window - win_paint_win(dpy, w, root_buffer); + // Dimming the window if needed + if (w->dim) { + XRenderComposite(dpy, PictOpOver, dim_picture, None, + root_buffer, 0, 0, 0, 0, x, y, wid, hei); } + XFixesDestroyRegion(dpy, paint_reg); + check_fade_fin(dpy, w); } @@ -1669,10 +1504,7 @@ paint_all(Display *dpy, XserverRegion region, win *t) { fflush(stdout); #endif - // Free up all temporary regions XFixesDestroyRegion(dpy, region); - XFixesDestroyRegion(dpy, reg_tmp); - XFixesDestroyRegion(dpy, reg_tmp2); if (root_buffer != root_picture) { XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, None); @@ -1710,10 +1542,6 @@ repair_win(Display *dpy, win *w) { w->a.y + w->a.border_width); } - // Remove the part in the damage area that could be ignored - if (!reg_ignore_expire && w->prev_trans && w->prev_trans->reg_ignore) - XFixesSubtractRegion(dpy, parts, parts, w->prev_trans->reg_ignore); - add_damage(dpy, parts); w->damaged = 1; } @@ -1750,6 +1578,30 @@ get_wintype_prop(Display *dpy, Window wid) { return WINTYPE_UNKNOWN; } +static wintype +determine_wintype(Display *dpy, Window w) { + Window *children = NULL; + unsigned int nchildren, i; + wintype type; + + type = get_wintype_prop(dpy, w); + if (type != WINTYPE_UNKNOWN) return type; + + if (!wid_get_children(dpy, w, &children, &nchildren)) + return WINTYPE_UNKNOWN; + + for (i = 0; i < nchildren; i++) { + type = determine_wintype(dpy, children[i]); + if (type != WINTYPE_UNKNOWN) return type; + } + + if (children) { + XFree((void *)children); + } + + return WINTYPE_UNKNOWN; +} + static void map_win(Display *dpy, Window id, unsigned long sequence, Bool fade, @@ -1758,8 +1610,6 @@ map_win(Display *dpy, Window id, if (!w) return; - reg_ignore_expire = True; - w->focused = False; w->a.map_state = IsViewable; @@ -1775,21 +1625,10 @@ map_win(Display *dpy, Window id, // Detect client window here instead of in add_win() as the client // window should have been prepared at this point if (!w->client_win) { - Window cw = 0; - // Always recursively look for a window with WM_STATE, as Fluxbox - // sets override-redirect flags on all frame windows. - cw = find_client_win(dpy, w->id); + Window cw = find_client_win(dpy, w->id); #ifdef DEBUG_CLIENTWIN printf("find_client_win(%#010lx): client %#010lx\n", w->id, cw); #endif - // Set a window's client window to itself only if we didn't find a - // client window and the window has override-redirect flag - if (!cw && w->a.override_redirect) { - cw = w->id; -#ifdef DEBUG_CLIENTWIN - printf("find_client_win(%#010lx): client self (override-redirected)\n", w->id); -#endif - } if (cw) { mark_client_win(dpy, w, cw); } @@ -1800,10 +1639,8 @@ map_win(Display *dpy, Window id, get_frame_extents(dpy, w, w->client_win); } - // Workaround for _NET_WM_WINDOW_TYPE for Openbox menus, which is - // set on a non-override-redirect window with no WM_STATE either - if (!w->client_win && WINTYPE_UNKNOWN == w->window_type) - w->window_type = get_wintype_prop(dpy, w->id); + if (WINTYPE_UNKNOWN == w->window_type) + w->window_type = determine_wintype(dpy, w->id); #ifdef DEBUG_WINTYPE printf("map_win(%#010lx): type %s\n", @@ -1897,7 +1734,9 @@ finish_unmap_win(Display *dpy, win *w) { w->extents = None; } +#if HAS_NAME_WINDOW_PIXMAP free_pixmap(dpy, &w->pixmap); +#endif free_picture(dpy, &w->picture); free_region(dpy, &w->border_size); @@ -1915,8 +1754,6 @@ unmap_win(Display *dpy, Window id, Bool fade) { if (!w) return; - reg_ignore_expire = True; - w->a.map_state = IsUnmapped; // Fading out @@ -1937,14 +1774,14 @@ unmap_win(Display *dpy, Window id, Bool fade) { } static opacity_t -wid_get_opacity_prop(Display *dpy, Window wid, opacity_t def) { +get_opacity_prop(Display *dpy, win *w, opacity_t def) { Atom actual; int format; unsigned long n, left; unsigned char *data; int result = XGetWindowProperty( - dpy, wid, opacity_atom, 0L, 1L, False, + dpy, w->id, opacity_atom, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, &data); if (result == Success && data != NULL) { @@ -1983,11 +1820,6 @@ determine_mode(Display *dpy, win *w) { mode = WINDOW_SOLID; } - // Expire reg_ignore if the window mode changes from solid to not, or - // vice versa - if ((WINDOW_SOLID == mode) != (WINDOW_SOLID == w->mode)) - reg_ignore_expire = True; - w->mode = mode; } @@ -2023,18 +1855,13 @@ calc_opacity(Display *dpy, win *w, Bool refetch_prop) { // Do not refetch the opacity window attribute unless necessary, this // is probably an expensive operation in some cases if (refetch_prop) { - w->opacity_prop = wid_get_opacity_prop(dpy, w->id, OPAQUE); - if (!opts.detect_client_opacity || !w->client_win - || w->id == w->client_win) - w->opacity_prop_client = OPAQUE; - else - w->opacity_prop_client = wid_get_opacity_prop(dpy, w->client_win, - OPAQUE); + w->opacity_prop = get_opacity_prop(dpy, w, OPAQUE); } - if (OPAQUE == (opacity = w->opacity_prop) - && OPAQUE == (opacity = w->opacity_prop_client)) { - opacity = opts.wintype_opacity[w->window_type] * OPAQUE; + if (OPAQUE == (opacity = w->opacity_prop)) { + if (1.0 != opts.wintype_opacity[w->window_type]) { + opacity = opts.wintype_opacity[w->window_type] * OPAQUE; + } } // Respect inactive_opacity in some cases @@ -2135,28 +1962,14 @@ static void mark_client_win(Display *dpy, win *w, Window client) { w->client_win = client; - XSelectInput(dpy, client, determine_evmask(dpy, client, WIN_EVMODE_CLIENT)); - // Get the frame width and monitor further frame width changes on client // window if necessary if (opts.frame_opacity) { get_frame_extents(dpy, w, client); } - - // Detect window type here + XSelectInput(dpy, client, determine_evmask(dpy, client, WIN_EVMODE_CLIENT)); if (WINTYPE_UNKNOWN == w->window_type) w->window_type = get_wintype_prop(dpy, w->client_win); - - // Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take - // override-redirect windows or windows without WM_TRANSIENT_FOR as - // _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG. - if (WINTYPE_UNKNOWN == w->window_type) { - if (w->a.override_redirect - || !wid_has_attr(dpy, client, transient_atom)) - w->window_type = WINTYPE_NORMAL; - else - w->window_type = WINTYPE_DIALOG; - } } static void @@ -2191,7 +2004,9 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) { #if CAN_DO_USABLE new->usable = False; #endif +#if HAS_NAME_WINDOW_PIXMAP new->pixmap = None; +#endif new->picture = None; if (new->a.class == InputOnly) { @@ -2212,10 +2027,10 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) { new->rounded_corners = False; new->border_size = None; - new->reg_ignore = None; new->extents = None; new->shadow = False; new->shadow_opacity = 0.0; + new->shadow_opacity_cur = 0.0; new->shadow_pict = None; new->shadow_alpha_pict = None; new->shadow_dx = 0; @@ -2224,13 +2039,14 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) { new->shadow_height = 0; new->opacity = 0; new->opacity_tgt = 0; + new->opacity_cur = OPAQUE; new->opacity_prop = OPAQUE; - new->opacity_prop_client = OPAQUE; new->fade = False; new->fade_callback = NULL; new->fade_fin = False; new->alpha_pict = None; new->frame_opacity = 1.0; + new->frame_opacity_cur = 1.0; new->frame_alpha_pict = None; new->dim = False; new->focused = False; @@ -2238,7 +2054,7 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) { new->need_configure = False; new->window_type = WINTYPE_UNKNOWN; - new->prev_trans = NULL; + new->prev_trans = 0; new->left_width = 0; new->right_width = 0; @@ -2349,8 +2165,6 @@ configure_win(Display *dpy, XConfigureEvent *ce) { restack_win(dpy, w, ce->above); } - reg_ignore_expire = True; - w->need_configure = False; #if CAN_DO_USABLE @@ -2367,8 +2181,10 @@ configure_win(Display *dpy, XConfigureEvent *ce) { w->a.y = ce->y; if (w->a.width != ce->width || w->a.height != ce->height) { +#if HAS_NAME_WINDOW_PIXMAP free_pixmap(dpy, &w->pixmap); free_picture(dpy, &w->picture); +#endif } if (w->a.width != ce->width || w->a.height != ce->height @@ -2419,9 +2235,10 @@ finish_destroy_win(Display *dpy, Window id) { finish_unmap_win(dpy, w); *prev = w->next; + free_picture(dpy, &w->alpha_pict); + free_picture(dpy, &w->frame_alpha_pict); free_picture(dpy, &w->shadow_pict); free_damage(dpy, &w->damage); - free_region(dpy, &w->reg_ignore); free(w->name); free(w->class_instance); free(w->class_general); @@ -2432,10 +2249,12 @@ finish_destroy_win(Display *dpy, Window id) { } } +#if HAS_NAME_WINDOW_PIXMAP static void destroy_callback(Display *dpy, win *w) { finish_destroy_win(dpy, w->id); } +#endif static void destroy_win(Display *dpy, Window id, Bool fade) { @@ -2962,17 +2781,12 @@ ev_property_notify(XPropertyEvent *ev) { } } - // If _NET_WM_OPACITY changes + /* check if Trans property was changed */ if (ev->atom == opacity_atom) { - win *w = NULL; - if ((w = find_win(dpy, ev->window))) - w->opacity_prop = wid_get_opacity_prop(dpy, w->id, OPAQUE); - else if (opts.detect_client_opacity - && (w = find_toplevel(dpy, ev->window))) - w->opacity_prop_client = wid_get_opacity_prop(dpy, w->client_win, - OPAQUE); + /* reset mode and redraw window */ + win *w = find_win(dpy, ev->window); if (w) { - calc_opacity(dpy, w, False); + calc_opacity(dpy, w, True); } } @@ -3041,22 +2855,7 @@ ev_shape_notify(XShapeEvent *ev) { } } -/** - * Handle ScreenChangeNotify events from X RandR extension. - */ -static void -ev_screen_change_notify(XRRScreenChangeNotifyEvent *ev) { - if (!opts.refresh_rate) { - update_refresh_rate(dpy); - if (!refresh_rate) { - fprintf(stderr, "ev_screen_change_notify(): Refresh rate detection " - "failed, software VSync disabled."); - opts.vsync = VSYNC_NONE; - } - } -} - -static void +inline static void ev_handle(XEvent *ev) { if ((ev->type & 0x7f) != KeymapNotify) { discard_ignore(dpy, ev->xany.serial); @@ -3130,10 +2929,6 @@ ev_handle(XEvent *ev) { ev_shape_notify((XShapeEvent *) ev); break; } - if (randr_exists && ev->type == (randr_event + RRScreenChangeNotify)) { - ev_screen_change_notify((XRRScreenChangeNotifyEvent *) ev); - break; - } if (ev->type == damage_event + XDamageNotify) { ev_damage_notify((XDamageNotifyEvent *)ev); } @@ -3145,14 +2940,11 @@ ev_handle(XEvent *ev) { * Main */ -/** - * Print usage text and exit. - */ static void usage(void) { - fputs( - "compton (v0.0.1)\n" - "usage: compton [options]\n" + fprintf(stderr, "compton (development version)\n"); + fprintf(stderr, "usage: compton [options]\n"); + fprintf(stderr, "Options:\n" "\n" "-d display\n" @@ -3219,27 +3011,6 @@ usage(void) { "--detect-rounded-corners\n" " Try to detect windows with rounded corners and don't consider\n" " them shaped windows.\n" - "--detect-client-opacity\n" - " Detect _NET_WM_OPACITY on client windows, useful for window\n" - " managers not passing _NET_WM_OPACITY of client windows to frame\n" - " windows.\n" - "\n" - "--refresh-rate val\n" - " Specify refresh rate of the screen. If not specified or 0, compton\n" - " will try detecting this with X RandR extension.\n" - "--vsync vsync-method\n" - " Set VSync method. There are 4 VSync methods currently available:\n" - " none = No VSync\n" - " sw = software VSync, basically limits compton to send a request\n" - " every 1 / refresh_rate second. Experimental.\n" - " drm = VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some\n" - " drivers. Experimental.\n" - " opengl = Try to VSync with SGI_swap_control OpenGL extension. Only\n" - " work on some drivers. Experimental.\n" - " (Note some VSync methods may not be enabled at compile time.)\n" - "--alpha-step val\n" - " Step for pregenerating alpha pictures. 0.01 - 1.0. Defaults to\n" - " 0.03.\n" "\n" "Format of a condition:\n" "\n" @@ -3256,77 +3027,26 @@ usage(void) { " flag is \"i\" (ignore case).\n" "\n" " is the actual pattern string.\n" - , stderr); + ); exit(1); } -/** - * Register a window as symbol, and initialize GLX context if wanted. - */ static void -register_cm(Bool want_glxct) { +register_cm(int scr) { + Window w; Atom a; char *buf; int len, s; -#ifdef CONFIG_VSYNC_OPENGL - // Create a window with the wanted GLX visual - if (want_glxct) { - XVisualInfo *pvi = NULL; - Bool ret = False; - // Get visual for the window - int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; - pvi = glXChooseVisual(dpy, scr, attribs); + if (scr < 0) return; - if (!pvi) { - fprintf(stderr, "register_cm(): Failed to choose visual required " - "by fake OpenGL VSync window. OpenGL VSync turned off.\n"); - } - else { - // Create the window - XSetWindowAttributes swa = { - .colormap = XCreateColormap(dpy, root, pvi->visual, AllocNone), - .border_pixel = 0, - }; - - pvi->screen = scr; - reg_win = XCreateWindow(dpy, root, 0, 0, 1, 1, 0, pvi->depth, - InputOutput, pvi->visual, CWBorderPixel | CWColormap, &swa); - - if (!reg_win) - fprintf(stderr, "register_cm(): Failed to create window required " - "by fake OpenGL VSync. OpenGL VSync turned off.\n"); - else { - // Get GLX context - glx_context = glXCreateContext(dpy, pvi, None, GL_TRUE); - if (!glx_context) { - fprintf(stderr, "register_cm(): Failed to get GLX context. " - "OpenGL VSync turned off.\n"); - opts.vsync = VSYNC_NONE; - } - else { - // Attach GLX context - if (!(ret = glXMakeCurrent(dpy, reg_win, glx_context))) - fprintf(stderr, "register_cm(): Failed to attach GLX context." - " OpenGL VSync turned off.\n"); - } - } - } - if (pvi) - XFree(pvi); - - if (!ret) - opts.vsync = VSYNC_NONE; - } -#endif - - if (!reg_win) - reg_win = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, - None, None); + w = XCreateSimpleWindow( + dpy, RootWindow(dpy, 0), + 0, 0, 1, 1, 0, None, None); Xutf8SetWMProperties( - dpy, reg_win, "xcompmgr", "xcompmgr", + dpy, w, "xcompmgr", "xcompmgr", NULL, 0, NULL, NULL, NULL); len = strlen(REGISTER_PROP) + 2; @@ -3343,7 +3063,7 @@ register_cm(Bool want_glxct) { a = XInternAtom(dpy, buf, False); free(buf); - XSetSelectionOwner(dpy, a, reg_win, 0); + XSetSelectionOwner(dpy, a, w, 0); } static void @@ -3551,13 +3271,6 @@ parse_config(char *cpath, struct options_tmp *pcfgtmp) { // --detect-rounded-corners lcfg_lookup_bool(&cfg, "detect-rounded-corners", &opts.detect_rounded_corners); - // --detect-client-opacity - lcfg_lookup_bool(&cfg, "detect-client-opacity", - &opts.detect_client_opacity); - // --refresh-rate - lcfg_lookup_int(&cfg, "refresh-rate", &opts.refresh_rate); - // --alpha-step - config_lookup_float(&cfg, "alpha-step", &opts.alpha_step); // --shadow-exclude { config_setting_t *setting = @@ -3620,19 +3333,9 @@ get_cfg(int argc, char *const *argv) { { "no-fading-openclose", no_argument, NULL, 265 }, { "shadow-ignore-shaped", no_argument, NULL, 266 }, { "detect-rounded-corners", no_argument, NULL, 267 }, - { "detect-client-opacity", no_argument, NULL, 268 }, - { "refresh-rate", required_argument, NULL, 269 }, - { "vsync", required_argument, NULL, 270 }, - { "alpha-step", required_argument, NULL, 271 }, // Must terminate with a NULL entry { NULL, 0, NULL, 0 }, }; - const static char * const vsync_str[] = { - "none", // VSYNC_NONE - "sw", // VSYNC_SW - "drm", // VSYNC_DRM - "opengl", // VSYNC_OPENGL - }; struct options_tmp cfgtmp = { .no_dock_shadow = False, @@ -3784,32 +3487,6 @@ get_cfg(int argc, char *const *argv) { // --detect-rounded-corners opts.detect_rounded_corners = True; break; - case 268: - // --detect-client-opacity - opts.detect_client_opacity = True; - break; - case 269: - // --refresh-rate - opts.refresh_rate = atoi(optarg); - break; - case 270: - // --vsync - { - vsync_t i; - for (i = 0; i < (sizeof(vsync_str) / sizeof(vsync_str[0])); ++i) - if (!strcasecmp(optarg, vsync_str[i])) { - opts.vsync = i; - break; - } - if ((sizeof(vsync_str) / sizeof(vsync_str[0])) == i) { - fputs("Invalid --vsync argument. Ignored.\n", stderr); - } - } - break; - case 271: - // --alpha-step - opts.alpha_step = atof(optarg); - break; default: usage(); break; @@ -3830,8 +3507,6 @@ get_cfg(int argc, char *const *argv) { opts.frame_opacity = normalize_d(opts.frame_opacity); opts.shadow_opacity = normalize_d(opts.shadow_opacity); cfgtmp.menu_opacity = normalize_d(cfgtmp.menu_opacity); - opts.refresh_rate = normalize_i_range(opts.refresh_rate, 0, 300); - opts.alpha_step = normalize_d_range(opts.alpha_step, 0.01, 1.0); if (OPAQUE == opts.inactive_opacity) { opts.inactive_opacity = 0; } @@ -3866,11 +3541,10 @@ get_atoms(void) { extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False); opacity_atom = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False); frame_extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False); - client_atom = XInternAtom(dpy, "WM_STATE", False); + client_atom = XA_WM_CLASS; name_atom = XA_WM_NAME; name_ewmh_atom = XInternAtom(dpy, "_NET_WM_NAME", False); class_atom = XA_WM_CLASS; - transient_atom = XA_WM_TRANSIENT_FOR; win_type_atom = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); @@ -3905,291 +3579,6 @@ get_atoms(void) { "_NET_WM_WINDOW_TYPE_DND", False); } -/** - * Update refresh rate info with X Randr extension. - */ -static void -update_refresh_rate(Display *dpy) { - XRRScreenConfiguration* randr_info; - - if (!(randr_info = XRRGetScreenInfo(dpy, root))) - return; - refresh_rate = XRRConfigCurrentRate(randr_info); - - XRRFreeScreenConfigInfo(randr_info); - - if (refresh_rate) - refresh_intv = NS_PER_SEC / refresh_rate; - else - refresh_intv = 0; -} - -/** - * Initialize software VSync. - * - * @return True for success, False otherwise - */ -static Bool -vsync_sw_init(void) { - // Prepare refresh rate - // Check if user provides one - refresh_rate = opts.refresh_rate; - if (refresh_rate) - refresh_intv = NS_PER_SEC / refresh_rate; - - // Auto-detect refresh rate otherwise - if (!refresh_rate && randr_exists) { - update_refresh_rate(dpy); - } - - // Turn off vsync_sw if we can't get the refresh rate - if (!refresh_rate) - return False; - - // Monitor screen changes only if vsync_sw is enabled and we are using - // an auto-detected refresh rate - if (randr_exists && !opts.refresh_rate) - XRRSelectInput(dpy, root, RRScreenChangeNotify); - - return True; -} - -/** - * Get current time in struct timespec. - * - * Note its starting time is unspecified. - */ -static inline struct timespec -get_time_timespec(void) { - struct timespec tm = { 0 }; - - clock_gettime(CLOCK_MONOTONIC, &tm); - - // Return a time of all 0 if the call fails - return tm; -} - -/** - * Get the smaller number that is bigger than dividend and is - * N times of divisor. - */ -static inline long -lceil_ntimes(long dividend, long divisor) { - // It's possible to use the more beautiful expression here: - // ret = ((dividend - 1) / divisor + 1) * divisor; - // But it does not work well for negative values. - long ret = dividend / divisor * divisor; - if (ret < dividend) - ret += divisor; - - return ret; -} - -/** - * Calculate time for which the program should wait for events if vsync_sw is - * enabled. - * - * @param timeout old timeout value, never negative! - * @return time to wait, in struct timespec - */ -static struct timespec -vsync_sw_ntimeout(int timeout) { - // Convert the old timeout to struct timespec - struct timespec next_paint_tmout = { - .tv_sec = timeout / MS_PER_SEC, - .tv_nsec = timeout % MS_PER_SEC * (NS_PER_SEC / MS_PER_SEC) - }; - // Get the nanosecond offset of the time when the we reach the timeout - // I don't think a 32-bit long could overflow here. - long target_relative_offset = (next_paint_tmout.tv_nsec + get_time_timespec().tv_nsec - paint_tm_offset) % NS_PER_SEC; - if (target_relative_offset < 0) - target_relative_offset += NS_PER_SEC; - - assert(target_relative_offset >= 0); - - // If the target time is sufficiently close to a VSync time, don't add - // an offset, to avoid certain blocking conditions. - if ((target_relative_offset % NS_PER_SEC) < VSYNC_SW_TOLERANCE) - return next_paint_tmout; - - // Add an offset so we wait until the next VSync after timeout - next_paint_tmout.tv_nsec += lceil_ntimes(target_relative_offset, refresh_intv) - target_relative_offset; - if (next_paint_tmout.tv_nsec > NS_PER_SEC) { - next_paint_tmout.tv_nsec -= NS_PER_SEC; - ++next_paint_tmout.tv_sec; - } - - return next_paint_tmout; -} - -/** - * Initialize DRM VSync. - * - * @return True for success, False otherwise - */ -static Bool -vsync_drm_init(void) { -#ifdef CONFIG_VSYNC_DRM - // Should we always open card0? - if ((drm_fd = open("/dev/dri/card0", O_RDWR)) < 0) { - fprintf(stderr, "vsync_drm_init(): Failed to open device.\n"); - return False; - } - - if (vsync_drm_wait()) - return False; - - return True; -#else - fprintf(stderr, "Program not compiled with DRM VSync support.\n"); - return False; -#endif -} - -#ifdef CONFIG_VSYNC_DRM -/** - * Wait for next VSync, DRM method. - * - * Stolen from: https://github.com/MythTV/mythtv/blob/master/mythtv/libs/libmythtv/vsync.cpp - */ -static int -vsync_drm_wait(void) { - int ret = -1; - drm_wait_vblank_t vbl; - - vbl.request.type = _DRM_VBLANK_RELATIVE, - vbl.request.sequence = 1; - - do { - ret = ioctl(drm_fd, DRM_IOCTL_WAIT_VBLANK, &vbl); - vbl.request.type &= ~_DRM_VBLANK_RELATIVE; - } while (ret && errno == EINTR); - - if (ret) - fprintf(stderr, "vsync_drm_wait(): VBlank ioctl did not work, " - "unimplemented in this drmver?\n"); - - return ret; - -} -#endif - -/** - * Initialize OpenGL VSync. - * - * Stolen from: http://git.tuxfamily.org/?p=ccm/cairocompmgr.git;a=commitdiff;h=efa4ceb97da501e8630ca7f12c99b1dce853c73e - * Possible original source: http://www.inb.uni-luebeck.de/~boehme/xvideo_sync.html - * - * @return True for success, False otherwise - */ -static Bool -vsync_opengl_init(void) { -#ifdef CONFIG_VSYNC_OPENGL - // Get video sync functions - glx_get_video_sync = (f_GetVideoSync) - glXGetProcAddress ((const GLubyte *) "glXGetVideoSyncSGI"); - glx_wait_video_sync = (f_WaitVideoSync) - glXGetProcAddress ((const GLubyte *) "glXWaitVideoSyncSGI"); - if (!glx_wait_video_sync || !glx_get_video_sync) { - fprintf(stderr, "vsync_opengl_init(): " - "Failed to get glXWait/GetVideoSyncSGI function.\n"); - return False; - } - - return True; -#else - fprintf(stderr, "Program not compiled with OpenGL VSync support.\n"); - return False; -#endif -} - -#ifdef CONFIG_VSYNC_OPENGL -/** - * Wait for next VSync, OpenGL method. - */ -static void -vsync_opengl_wait(void) { - unsigned vblank_count; - - glx_get_video_sync(&vblank_count); - glx_wait_video_sync(2, (vblank_count + 1) % 2, &vblank_count); - // I see some code calling glXSwapIntervalSGI(1) afterwards, is it required? -} -#endif - -/** - * Wait for next vsync and timeout unless new events appear. - * - * @param fd struct pollfd used for poll() - * @param timeout second timeout (fading timeout) - * @return > 0 if we get some events, 0 if timeout is reached, < 0 on - * problems - */ -static Bool -vsync_wait(Display *dpy, struct pollfd *fd, int timeout) { - // Always wait infinitely if asked so, to minimize CPU usage - if (timeout < 0) { - int ret = poll(fd, 1, timeout); - // Reset fade_time so the fading steps during idling are not counted - fade_time = get_time_ms(); - return ret; - } - - if (VSYNC_NONE == opts.vsync) - return poll(fd, 1, timeout); - - // vsync_sw: Wait until the next sync right after next fading timeout - if (VSYNC_SW == opts.vsync) { - struct timespec new_tmout = vsync_sw_ntimeout(timeout); - // printf("ppoll(): %3ld:%09ld\n", new_tmout.tv_sec, new_tmout.tv_nsec); - return ppoll(fd, 1, &new_tmout, NULL); - } - -#ifdef CONFIG_VSYNC_DRM - // vsync_drm: We are not accepting events when waiting for next sync, - // so I guess this would generate a latency of at most one frame. I'm - // not sure if it's possible to add some smart logic in vsync_drm_wait() - // to avoid this problem, unless I could find more documentation... - if (VSYNC_DRM == opts.vsync) { - vsync_drm_wait(); - return 0; - } -#endif - -#ifdef CONFIG_VSYNC_OPENGL - // vsync_opengl: Same one-frame-latency issue, well, not sure how to deal it - // here. - if (VSYNC_OPENGL == opts.vsync) { - vsync_opengl_wait(); - return 0; - } -#endif - - // This place should not reached! - assert(0); - - return 0; -} - -/** - * Pregenerate alpha pictures. - */ -static void -init_alpha_picts(Display *dpy) { - int i; - int num = lround(1.0 / opts.alpha_step) + 1; - - alpha_picts = malloc(sizeof(Picture) * num); - - for (i = 0; i < num; ++i) { - double o = i * opts.alpha_step; - if ((1.0 - o) > opts.alpha_step) - alpha_picts[i] = solid_picture(dpy, False, o, 0, 0, 0); - else - alpha_picts[i] = None; - } -} - int main(int argc, char **argv) { XEvent ev; @@ -4210,7 +3599,7 @@ main(int argc, char **argv) { get_cfg(argc, argv); - fade_time = get_time_ms(); + fade_time = get_time_in_milliseconds(); dpy = XOpenDisplay(opts.display); if (!dpy) { @@ -4239,9 +3628,11 @@ main(int argc, char **argv) { XCompositeQueryVersion(dpy, &composite_major, &composite_minor); +#if HAS_NAME_WINDOW_PIXMAP if (composite_major > 0 || composite_minor >= 2) { has_name_pixmap = True; } +#endif if (!XDamageQueryExtension(dpy, &damage_event, &damage_error)) { fprintf(stderr, "No damage extension\n"); @@ -4253,44 +3644,15 @@ main(int argc, char **argv) { exit(1); } - // Query X Shape - if (XShapeQueryExtension(dpy, &shape_event, &shape_error)) { - shape_exists = True; + if (!XShapeQueryExtension(dpy, &shape_event, &shape_error)) { + shape_exists = False; } - // Query X RandR - if (VSYNC_SW == opts.vsync && !opts.refresh_rate) { - if (XRRQueryExtension(dpy, &randr_event, &randr_error)) - randr_exists = True; - else - fprintf(stderr, "No XRandR extension, automatic refresh rate " - "detection impossible.\n"); - } - -#ifdef CONFIG_VSYNC_OPENGL - // Query X GLX extension - if (VSYNC_OPENGL == opts.vsync) { - if (glXQueryExtension(dpy, &glx_event, &glx_error)) - glx_exists = True; - else { - fprintf(stderr, "No GLX extension, OpenGL VSync impossible.\n"); - opts.vsync = VSYNC_NONE; - } - } -#endif - - register_cm((VSYNC_OPENGL == opts.vsync)); - - // Initialize software/DRM/OpenGL VSync - if ((VSYNC_SW == opts.vsync && !vsync_sw_init()) - || (VSYNC_DRM == opts.vsync && !vsync_drm_init()) - || (VSYNC_OPENGL == opts.vsync && !vsync_opengl_init())) - opts.vsync = VSYNC_NONE; + register_cm(scr); if (opts.fork_after_register) fork_after(); get_atoms(); - init_alpha_picts(dpy); pa.subwindow_mode = IncludeInferiors; @@ -4350,51 +3712,31 @@ main(int argc, char **argv) { ufd.fd = ConnectionNumber(dpy); ufd.events = POLLIN; -#ifdef DEBUG_REPAINT - struct timespec last_paint = get_time_timespec(); -#endif - - if (VSYNC_SW == opts.vsync) - paint_tm_offset = get_time_timespec().tv_nsec; - - reg_ignore_expire = True; - t = paint_preprocess(dpy, list); - paint_all(dpy, None, t); // Initialize idling idling = False; - // Main loop - while (1) { - Bool ev_received = False; + for (;;) { + do { + if (!QLength(dpy)) { + if (poll(&ufd, 1, (idling ? -1: fade_timeout())) == 0) { + break; + } + } - while (QLength(dpy) - || (vsync_wait(dpy, &ufd, - (ev_received ? 0: (idling ? -1: fade_timeout()))) > 0)) { XNextEvent(dpy, &ev); - ev_handle((XEvent *) &ev); - ev_received = True; - } + ev_handle((XEvent *)&ev); + } while (QLength(dpy)); // idling will be turned off during paint_preprocess() if needed idling = True; t = paint_preprocess(dpy, list); - - if (all_damage && !is_region_empty(dpy, all_damage)) { -#ifdef DEBUG_REPAINT - struct timespec now = get_time_timespec(); - struct timespec diff = { 0 }; - timespec_subtract(&diff, &now, &last_paint); - printf("[ %5ld:%09ld ] ", diff.tv_sec, diff.tv_nsec); - last_paint = now; -#endif - + if (all_damage) { static int paint; paint_all(dpy, all_damage, t); - reg_ignore_expire = False; paint++; XSync(dpy, False); all_damage = None; diff --git a/src/compton.h b/src/compton.h index 6aac338..83b7876 100644 --- a/src/compton.h +++ b/src/compton.h @@ -26,10 +26,6 @@ // #define CONFIG_REGEX_PCRE_JIT 1 // Whether to enable parsing of configuration files using libconfig // #define CONFIG_LIBCONFIG 1 -// Whether to enable DRM VSync support -// #define CONFIG_VSYNC_DRM 1 -// Whether to enable OpenGL VSync support -// #define CONFIG_VSYNC_OPENGL 1 // === Includes === @@ -48,7 +44,6 @@ #include #include #include -#include #include @@ -74,25 +69,10 @@ #include #include #include -#include - -#ifdef CONFIG_VSYNC_DRM -#include -// We references some definitions in drm.h, which could also be found in -// /usr/src/linux/include/drm/drm.h, but that path is probably even less -// reliable than libdrm -#include -#include -#include -#endif - -#ifdef CONFIG_VSYNC_OPENGL -#include -#endif // === Constants === -#if !(COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2) -#error libXcomposite version unsupported +#if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2 +#define HAS_NAME_WINDOW_PIXMAP 1 #endif #define ROUNDED_PERCENT 0.05 @@ -109,13 +89,6 @@ extern struct timeval time_start; #define WINDOW_TRANS 1 #define WINDOW_ARGB 2 -#define FADE_DELTA_TOLERANCE 0.2 -#define VSYNC_SW_TOLERANCE 1000 - -#define NS_PER_SEC 1000000000L -#define US_PER_SEC 1000000L -#define MS_PER_SEC 1000 - // Window flags // Window size is changed @@ -183,7 +156,9 @@ typedef struct _win { struct _win *next; Window id; Window client_win; +#if HAS_NAME_WINDOW_PIXMAP Pixmap pixmap; +#endif XWindowAttributes a; #if CAN_DO_USABLE Bool usable; /* mapped and all damaged at one point */ @@ -219,12 +194,10 @@ typedef struct _win { opacity_t opacity; /// Target window opacity. opacity_t opacity_tgt; + /// Opacity of current alpha_pict. + opacity_t opacity_cur; /// Cached value of opacity window attribute. opacity_t opacity_prop; - /// Cached value of opacity window attribute on client window. For - /// broken window managers not transferring client window's - /// _NET_WM_OPACITY value - opacity_t opacity_prop_client; /// Alpha mask Picture to render window with opacity. Picture alpha_pict; @@ -240,6 +213,8 @@ typedef struct _win { // Frame-opacity-related members /// Current window frame opacity. Affected by window opacity. double frame_opacity; + /// Opacity of current frame_alpha_pict. + opacity_t frame_opacity_cur; /// Alpha mask Picture to render window frame with opacity. Picture frame_alpha_pict; /// Frame widths. Determined by client window attributes. @@ -250,6 +225,8 @@ typedef struct _win { Bool shadow; /// Opacity of the shadow. Affected by window opacity and frame opacity. double shadow_opacity; + /// Opacity of current shadow_pict. + double shadow_opacity_cur; /// X offset of shadow. Affected by commandline argument. int shadow_dx; /// Y offset of shadow. Affected by commandline argument. @@ -274,27 +251,10 @@ typedef struct _win { Bool need_configure; XConfigureEvent queue_configure; - /// Region to be ignored when painting. Basically the region where - /// higher opaque windows will paint upon. Depends on window frame - /// opacity state, window geometry, window mapped/unmapped state, - /// window mode, of this and all higher windows. - XserverRegion reg_ignore; struct _win *prev_trans; } win; -typedef enum _vsync_t { - VSYNC_NONE, - VSYNC_SW, - VSYNC_DRM, - VSYNC_OPENGL, -} vsync_t; - -#ifdef CONFIG_VSYNC_OPENGL -typedef int (*f_WaitVideoSync) (int, int, unsigned *); -typedef int (*f_GetVideoSync) (unsigned *); -#endif - typedef struct _options { // General char *display; @@ -309,12 +269,6 @@ typedef struct _options { /// Whether to work under synchronized mode for debugging. Bool synchronize; - // VSync - /// User-specified refresh rate. - int refresh_rate; - /// VSync method to use; - vsync_t vsync; - // Shadow Bool wintype_shadow[NUM_WINTYPES]; /// Red, green and blue tone of the shadow. @@ -348,16 +302,9 @@ typedef struct _options { /// Whether inactive_opacity overrides the opacity set by window /// attributes. Bool inactive_opacity_override; - /// Frame opacity. Relative to window opacity, also affects shadow - /// opacity. double frame_opacity; - /// Whether to detect _NET_WM_OPACITY on client windows. Used on window - /// managers that don't pass _NET_WM_OPACITY to frame windows. - Bool detect_client_opacity; /// How much to dim an inactive window. 0.0 - 1.0, 0 to disable. double inactive_dim; - /// Step for pregenerating alpha pictures. 0.01 - 1.0. - double alpha_step; // Calculated /// Whether compton needs to track focus changes. @@ -407,16 +354,6 @@ set_ignore(Display *dpy, unsigned long sequence); static int should_ignore(Display *dpy, unsigned long sequence); -/** - * Subtract two unsigned long values. - * - * Truncate to 0 if the result is negative. - */ -static inline unsigned long -sub_unslong(unsigned long a, unsigned long b) { - return (a > b) ? a - b : 0; -} - /** * Set a Bool array of all wintypes to true. */ @@ -578,41 +515,6 @@ timeval_subtract(struct timeval *result, return x->tv_sec < y->tv_sec; } -/* - * Subtracting two struct timespec values. - * - * Taken from glibc manual. - * - * Subtract the `struct timespec' values X and Y, - * storing the result in RESULT. - * Return 1 if the difference is negative, otherwise 0. - */ -static inline int -timespec_subtract(struct timespec *result, - struct timespec *x, - struct timespec *y) { - /* Perform the carry for the later subtraction by updating y. */ - if (x->tv_nsec < y->tv_nsec) { - int nsec = (y->tv_nsec - x->tv_nsec) / NS_PER_SEC + 1; - y->tv_nsec -= NS_PER_SEC * nsec; - y->tv_sec += nsec; - } - - if (x->tv_nsec - y->tv_nsec > NS_PER_SEC) { - int nsec = (x->tv_nsec - y->tv_nsec) / NS_PER_SEC; - y->tv_nsec += NS_PER_SEC * nsec; - y->tv_sec -= nsec; - } - - /* Compute the time remaining to wait. - tv_nsec is certainly positive. */ - result->tv_sec = x->tv_sec - y->tv_sec; - result->tv_nsec = x->tv_nsec - y->tv_nsec; - - /* Return 1 if result is negative. */ - return x->tv_sec < y->tv_sec; -} - /** * Print time passed since program starts execution. * @@ -675,7 +577,7 @@ free_damage(Display *dpy, Damage *p) { } static unsigned long -get_time_ms(void); +get_time_in_milliseconds(void); static int fade_timeout(void); @@ -729,7 +631,8 @@ solid_picture(Display *dpy, Bool argb, double a, static inline bool is_normal_win(const win *w) { return (WINTYPE_NORMAL == w->window_type - || WINTYPE_UTILITY == w->window_type); + || WINTYPE_UTILITY == w->window_type + || WINTYPE_UNKNOWN == w->window_type); } /** @@ -858,6 +761,9 @@ repair_win(Display *dpy, win *w); static wintype get_wintype_prop(Display * dpy, Window w); +static wintype +determine_wintype(Display *dpy, Window w); + static void map_win(Display *dpy, Window id, unsigned long sequence, Bool fade, @@ -869,14 +775,16 @@ finish_map_win(Display *dpy, win *w); static void finish_unmap_win(Display *dpy, win *w); +#if HAS_NAME_WINDOW_PIXMAP static void unmap_callback(Display *dpy, win *w); +#endif static void unmap_win(Display *dpy, Window id, Bool fade); static opacity_t -wid_get_opacity_prop(Display *dpy, Window wid, opacity_t def); +get_opacity_prop(Display *dpy, win *w, opacity_t def); static double get_opacity_percent(Display *dpy, win *w); @@ -927,8 +835,10 @@ circulate_win(Display *dpy, XCirculateEvent *ce); static void finish_destroy_win(Display *dpy, Window id); +#if HAS_NAME_WINDOW_PIXMAP static void destroy_callback(Display *dpy, win *w); +#endif static void destroy_win(Display *dpy, Window id, Bool fade); @@ -970,7 +880,7 @@ static void usage(void); static void -register_cm(Bool want_glxct); +register_cm(int scr); inline static void ev_focus_in(XFocusChangeEvent *ev); @@ -1037,39 +947,6 @@ copy_region(Display *dpy, XserverRegion oldregion) { return region; } -/** - * Dump a region. - */ -static inline void -dump_region(Display *dpy, XserverRegion region) { - int nrects = 0, i; - XRectangle *rects = XFixesFetchRegion(dpy, region, &nrects); - if (!rects) - return; - - for (i = 0; i < nrects; ++i) - printf("Rect #%d: %8d, %8d, %8d, %8d\n", i, rects[i].x, rects[i].y, - rects[i].width, rects[i].height); - - XFree(rects); -} - -/** - * Check if a region is empty. - * - * Keith Packard said this is slow: - * http://lists.freedesktop.org/archives/xorg/2007-November/030467.html - */ -static inline Bool -is_region_empty(Display *dpy, XserverRegion region) { - int nrects = 0; - XRectangle *rects = XFixesFetchRegion(dpy, region, &nrects); - - XFree(rects); - - return !nrects; -} - /** * Add a window to damaged area. * @@ -1125,34 +1002,3 @@ get_cfg(int argc, char *const *argv); static void get_atoms(void); - -static void -update_refresh_rate(Display *dpy); - -static Bool -vsync_sw_init(void); - -static struct timespec -vsync_sw_ntimeout(int timeout); - -static Bool -vsync_drm_init(void); - -#ifdef CONFIG_VSYNC_DRM -static int -vsync_drm_wait(void); -#endif - -static Bool -vsync_opengl_init(void); - -#ifdef CONFIG_VSYNC_OPENGL -static void -vsync_opengl_wait(void); -#endif - -static Bool -vsync_wait(Display *dpy, struct pollfd *fd, int timeout); - -static void -init_alpha_picts(Display *dpy); From 9399db5377ed04fa464e214a1155134c87c14abc Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Oct 2012 07:41:24 -0500 Subject: [PATCH 3/6] update readme and man page. --- LICENSE | 4 ++ README.md | 186 ++++++++++++++++++++++++++++++++++++-------------- man/compton.1 | 122 +++++++++++++++++++++++++-------- 3 files changed, 231 insertions(+), 81 deletions(-) diff --git a/LICENSE b/LICENSE index a64b148..5d93431 100644 --- a/LICENSE +++ b/LICENSE @@ -1,10 +1,14 @@ compton - a compositor for X11 +Contributors + Based on xcompmgr, originally written by Keith Packard, with modifications from several contributors (according to the xcompmgr man page): Matthew Allum, Eric Anholt, Dan Doel, Thomas Luebking, Matthew Hawn, Ely Levy, Phil Blundell, and Carl Worth. Menu transparency was implemented by Dana Jansens. +Numerous contributions to compton from Richard Grenville. + xcompmgr Copyright © 2003 Keith Packard diff --git a/README.md b/README.md index d3dfc5c..85bac0c 100644 --- a/README.md +++ b/README.md @@ -17,22 +17,22 @@ partially doing this out of a desire to learn Xlib. * shadows are now enabled for argb windows, e.g. terminals with transparency * removed serverside shadows (and simple compositing) to clean the code, the only option that remains is clientside shadows - -The above features give compton a feature set similar to the xfce compositor. - -Compton has only been tested with openbox so far, but frame transparency -should work with any window manager that properly sets `_NET_FRAME_EXTENTS`. +* configuration files (specified with `--config`) +* colored shadows (with `--shadow-[red/green/blue] value`) +* a new fade system +* vsync (still under development) +* several more options ## Fixes from the original xcompmgr: * fixed a segfault when opening certain window types * fixed a memory leak caused by not freeing up shadows (from the freedesktop repo) +* fixed the conflict with chromium and similar windows +* [many more](https://github.com/chjj/compton/issues) ## Building -The same dependencies as xcompmgr. - ### Dependencies: __B__ for build-time @@ -60,67 +60,147 @@ $ make $ make install ``` -## Usage +## Example Usage ``` bash -$ compton -cC -i 0.6 -e 0.6 $ compton -cC -i 0.6 -e 0.6 -fF -$ compton -cC -fF -I 0.065 -O 0.065 -D 6 -m 0.8 -i 0.6 -e 0.6 +$ compton --config ~/compton.conf ``` -### Options +### Options and Configuration - compton [-d display] [-r radius] [-o opacity] - [-l left-offset] [-t top-offset] - [-i opacity] [-e opacity] [-cCfFSdG] +``` +compton [-d display] [-r radius] [-o opacity] + [-l left-offset] [-t top-offset] + [-i opacity] [-e opacity] [-cCfFSdG] + [--config path] [--shadow-red value] + [--shadow-gren value] [--shadow-blue value] + [--inactive-opacity-override] [--inactive-dim value] + [--mark-wmwin-focused] [--shadow-exclude condition] + [--mark-ovredir-focused] [--no-fading-openclose] + [--shadow-ignore-shaped] [--detect-round-corners] +``` -* `-d` __display__ - Specifies the display to manage. -* `-r` __radius__ - Specifies the blur radius for client-side shadows. -* `-o` __opacity__ - Specifies the opacity for client-side shadows. -* `-l` __left-offset__ - Specifies the left offset for client-side shadows. -* `-t` __top-offset__ - Specifies the top offset for client-side shadows. -* `-I` __fade-in-step__ - Specifies the opacity change between steps while fading in. -* `-O` __fade-out-step__ - Specifies the opacity change between steps while fading out. -* `-D` __fade-delta__ - Specifies the time (in milliseconds) between steps in a fade. -* `-c` - Enable client-side shadows on windows. -* `-f` - When -c is specified, enables a smooth fade effect for transient windows like - menus, and for all windows on hide and restore events. -* `-C` - When -c is specified, attempts to avoid painting shadows on panels and docks. -* `-F` - When -f is specified, also enables the fade effect when windows change their - opacity, as with transset(1). -* `-i` __opacity__ - Specifies inactive window transparency. (0.1 - 1.0) -* `-e` __opacity__ - Specifies window frame transparency. (0.1 - 1.0) -* `-G` - Avoid painting shadows on DND windows. -* `-b` __daemonize__ - Attempt to daemonize process. -* `-S` - Enables synchronous operation. Useful for debugging. +* `-d` __display__: + Which display should be managed. +* `-r` __radius__: + The blur radius for shadows. (default 12) +* `-o` __opacity__: + The translucency for shadows. (default .75) +* `-l` __left-offset__: + The left offset for shadows. (default -15) +* `-t` __top-offset__: + The top offset for shadows. (default -15) +* `-I` __fade-in-step__: + Opacity change between steps while fading in. (default 0.028) +* `-O` __fade-out-step__: + Opacity change between steps while fading out. (default 0.03) +* `-D` __fade-delta-time__: + The time between steps in a fade in milliseconds. (default 10) +* `-m` __opacity__: + The opacity for menus. (default 1.0) +* `-c`: + Enabled client-side shadows on windows. +* `-C`: + Avoid drawing shadows on dock/panel windows. +* `-z`: + Zero the part of the shadow's mask behind the window (experimental). +* `-f`: + Fade windows in/out when opening/closing and when opacity + changes, unless --no-fading-openclose is used. +* `-F`: + Equals -f. Deprecated. +* `-i` __opacity__: + Opacity of inactive windows. (0.1 - 1.0) +* `-e` __opacity__: + Opacity of window titlebars and borders. (0.1 - 1.0) +* `-G`: + Don't draw shadows on DND windows +* `-b` __daemonize__: + Daemonize process. +* `-S`: + Enable synchronous operation (for debugging). +* `--config` __path__: + Look for configuration file at the path. +* `--shadow-red` __value__: + Red color value of shadow (0.0 - 1.0, defaults to 0). +* `--shadow-green` __value__: + Green color value of shadow (0.0 - 1.0, defaults to 0). +* `--shadow-blue` __value__: + Blue color value of shadow (0.0 - 1.0, defaults to 0). +* `--inactive-opacity-override`: + Inactive opacity set by -i overrides value of _NET_WM_OPACITY. +* `--inactive-dim` __value__: + Dim inactive windows. (0.0 - 1.0, defaults to 0) +* `--mark-wmwin-focused`: + Try to detect WM windows and mark them as active. +* `--shadow-exclude` __condition__: + Exclude conditions for shadows. +* `--mark-ovredir-focused`: + Mark over-redirect windows as active. +* `--no-fading-openclose`: + Do not fade on window open/close. +* `--shadow-ignore-shaped`: + Do not paint shadows on shaped windows. +* `--detect-rounded-corners`: + Try to detect windows with rounded corners and don't consider + them shaped windows. + +### Format of a condition: + +`condition = :[]:` + +`` is one of `"n"` (window name), `"i"` (window class +instance), and `"g"` (window general class) + +`` is one of `"e"` (exact match), `"a"` (match anywhere), +`"s"` (match from start), `"w"` (wildcard), and `"p"` (PCRE +regular expressions, if compiled with the support). + +`` could be a series of flags. Currently the only defined +flag is `"i"` (ignore case). + +`` is the actual pattern string. + +### Configuration + +A more robust +[sample configuration file](https://raw.github.com/chjj/compton/master/compton.sample.conf) +is available in the repository. + +#### Example + +~/compton.conf: + +``` +# Shadows +shadow = true; + +# Opacity +inactive-opacity = 0.8; +frame-opacity = 0.7; + +# Fades +fading = true; +``` + +Run with: + +``` bash +$ compton --config ~/compton.conf +``` ## License -xcompmgr has gotten around. As far as I can tell, the lineage for this -particular tree is something like: +Although compton has kind of taken on a life of its own, it was originally +an xcompmgr fork. xcompmgr has gotten around. As far as I can tell, the lineage +for this particular tree is something like: * Keith Packard (original author) * Matthew Hawn * ... * Dana Jansens -* Myself +* chjj and richardgv Not counting the tens of people who forked it in between. diff --git a/man/compton.1 b/man/compton.1 index 176a6ec..0ff4691 100644 --- a/man/compton.1 +++ b/man/compton.1 @@ -4,7 +4,14 @@ compton \- a compositor for X11 .SH SYNOPSIS .nf -.B compton [\-d display] [\-r radius] [\-o opacity] [\-l left-offset] [\-t top-offset] [\-i opacity] [\-e opacity] [\-cCfFSdG] +.B compton [\-d display] [\-r radius] [\-o opacity] [\-l left-offset] + [\-t top-offset] [\-i opacity] [\-e opacity] [\-cCfFSdG] + [\--config path] [\--shadow-red value] + [\--shadow-gren value] [\--shadow-blue value] + [\--inactive-opacity-override] [\--inactive-dim value] + [\--mark-wmwin-focused] [\--shadow-exclude condition] + [\--mark-ovredir-focused] [\--no-fading-openclose] + [\--shadow-ignore-shaped] [\--detect-round-corners] .fi .SH DESCRIPTION .B compton @@ -15,62 +22,121 @@ and shadows on argb windows. .SH OPTIONS .TP .BI \-d\ display -Specifies the display to manage. +Which display should be managed. .TP .BI \-r\ radius -Specifies the blur radius for client-side shadows. +The blur radius for shadows. (default 12) .TP .BI \-o\ opacity -Specifies the opacity for client-side shadows. +The translucency for shadows. (default .75) .TP .BI \-l\ left-offset -Specifies the left offset for client-side shadows. +The left offset for shadows. (default -15) .TP .BI \-t\ top-offset -Specifies the top offset for client-side shadows. +The top offset for shadows. (default -15) .TP .BI \-I\ fade-in-step -Specifies the opacity change between steps while fading in. +Opacity change between steps while fading in. (default 0.028) .TP .BI \-O\ fade-out-step -Specifies the opacity change between steps while fading out. +Opacity change between steps while fading out. (default 0.03) .TP -.BI \-D\ fade-delta -Specifies the time (in milliseconds) between steps in a fade. +.BI \-D\ fade-delta-time +The time between steps in a fade in milliseconds. (default 10) +.TP +.BI \-m\ opacity +The opacity for menus. (default 1.0) .TP .BI \-c -Enable client-side shadows on windows. -.TP -.BI \-f -When \-c is specified, enables a smooth fade effect for transient windows like -menus, and for all windows on hide and restore events. +Enabled client-side shadows on windows. .TP .BI \-C -When \-c is specified, attempts to avoid painting shadows on panels and docks. +Avoid drawing shadows on dock/panel windows. .TP -.BI \-G -When \-c is specified, attempts to avoid painting shadows on -drag-and-drop windows. +.BI \-z +Zero the part of the shadow's mask behind the window (experimental). +.TP +.BI \-f +Fade windows in/out when opening/closing and when opacity +changes, unless --no-fading-openclose is used. .TP .BI \-F -When \-f is specified, also enables the fade effect when windows change their -opacity, as with transset(1). -.TP -.BI \-b -Attempt to fork to background after registering compositor. +Equals -f. Deprecated. .TP .BI \-i\ opacity -Specifies inactive window transparency. (0.1 - 1.0) +Opacity of inactive windows. (0.1 - 1.0) .TP .BI \-e\ opacity -Specifies window frame transparency. (0.1 - 1.0) +Opacity of window titlebars and borders. (0.1 - 1.0) +.TP +.BI \-G +Don't draw shadows on DND windows +.TP +.BI \-b\ daemonize +Daemonize process. .TP .BI \-S -Enables synchronous operation. Useful for debugging. +Enable synchronous operation (for debugging). +.TP +.BI \--config\ path +Look for configuration file at the path. +.TP +.BI \--shadow-red\ value +Red color value of shadow (0.0 - 1.0, defaults to 0). +.TP +.BI \--shadow-green\ value +Green color value of shadow (0.0 - 1.0, defaults to 0). +.TP +.BI \--shadow-blue\ value +Blue color value of shadow (0.0 - 1.0, defaults to 0). +.TP +.BI \--inactive-opacity-override +Inactive opacity set by -i overrides value of _NET_WM_OPACITY. +.TP +.BI \--inactive-dim\ value +Dim inactive windows. (0.0 - 1.0, defaults to 0) +.TP +.BI \--mark-wmwin-focused +Try to detect WM windows and mark them as active. +.TP +.BI \--shadow-exclude\ condition +Exclude conditions for shadows. +.TP +.BI \--mark-ovredir-focused +Mark over-redirect windows as active. +.TP +.BI \--no-fading-openclose +Do not fade on window open/close. +.TP +.BI \--shadow-ignore-shaped +Do not paint shadows on shaped windows. +.TP +.BI \--detect-rounded-corners +Try to detect windows with rounded corners and don't consider +them shaped windows. +.TP +.BI Format\ of\ a\ condition: + +condition = :[]: + + is one of "n" (window name), "i" (window class +instance), and "g" (window general class) + + is one of "e" (exact match), "a" (match anywhere), +"s" (match from start), "w" (wildcard), and "p" (PCRE +regular expressions, if compiled with the support). + + could be a series of flags. Currently the only defined +flag is "i" (ignore case). + + is the actual pattern string. + .SH BUGS Please report any you find to https://github.com/chjj/compton. .SH AUTHORS xcompmgr, originally written by Keith Packard, with contributions from Matthew Allum, Eric Anholt, Dan Doel, Thomas Luebking, Matthew Hawn, Ely Levy, Phil Blundell, and Carl Worth. -Compton by Christopher Jeffrey, based on Dana Jansens' original work. +Compton by Christopher Jeffrey, based on Dana Jansens' original work, +with numerous contributions from Richard Grenville. From 7e1a7ee1201c5a88b61c672dd313925db6914d40 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Oct 2012 08:20:43 -0500 Subject: [PATCH 4/6] fix man page and various other documentation. --- README.md | 8 ++++---- man/compton.1 | 29 ++++++++++++++++++----------- src/compton.c | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 85bac0c..64b76f2 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ $ make install ## Example Usage ``` bash -$ compton -cC -i 0.6 -e 0.6 -fF +$ compton -cC -i 0.6 -e 0.6 -f $ compton --config ~/compton.conf ``` @@ -74,7 +74,7 @@ compton [-d display] [-r radius] [-o opacity] [-l left-offset] [-t top-offset] [-i opacity] [-e opacity] [-cCfFSdG] [--config path] [--shadow-red value] - [--shadow-gren value] [--shadow-blue value] + [--shadow-green value] [--shadow-blue value] [--inactive-opacity-override] [--inactive-dim value] [--mark-wmwin-focused] [--shadow-exclude condition] [--mark-ovredir-focused] [--no-fading-openclose] @@ -116,8 +116,8 @@ compton [-d display] [-r radius] [-o opacity] Opacity of window titlebars and borders. (0.1 - 1.0) * `-G`: Don't draw shadows on DND windows -* `-b` __daemonize__: - Daemonize process. +* `-b`: + Daemonize/background process. * `-S`: Enable synchronous operation (for debugging). * `--config` __path__: diff --git a/man/compton.1 b/man/compton.1 index 0ff4691..cdaa234 100644 --- a/man/compton.1 +++ b/man/compton.1 @@ -1,24 +1,27 @@ .ds q \N'34' .TH compton 1 + .SH NAME compton \- a compositor for X11 + .SH SYNOPSIS -.nf -.B compton [\-d display] [\-r radius] [\-o opacity] [\-l left-offset] - [\-t top-offset] [\-i opacity] [\-e opacity] [\-cCfFSdG] - [\--config path] [\--shadow-red value] - [\--shadow-gren value] [\--shadow-blue value] - [\--inactive-opacity-override] [\--inactive-dim value] - [\--mark-wmwin-focused] [\--shadow-exclude condition] - [\--mark-ovredir-focused] [\--no-fading-openclose] - [\--shadow-ignore-shaped] [\--detect-round-corners] -.fi +.B compton +[\-d display] [\-r radius] [\-o opacity] [\-l left\-offset] +[\-t top\-offset] [\-i opacity] [\-e opacity] [\-cCfFSdG] +[\-\-config path] [\-\-shadow\-red value] +[\-\-shadow\-green value] [\-\-shadow\-blue value] +[\-\-inactive\-opacity\-override] [\-\-inactive\-dim value] +[\-\-mark\-wmwin\-focused] [\-\-shadow\-exclude condition] +[\-\-mark\-ovredir\-focused] [\-\-no\-fading\-openclose] +[\-\-shadow\-ignore\-shaped] [\-\-detect\-round\-corners] + .SH DESCRIPTION .B compton is a compositor based on Dana Jansens' version of xcompmgr (which itself was written by Keith Packard). It includes many improvements over the original xcompmgr, including window frame opacity, inactive window transparency, and shadows on argb windows. + .SH OPTIONS .TP .BI \-d\ display @@ -73,7 +76,7 @@ Opacity of window titlebars and borders. (0.1 - 1.0) .BI \-G Don't draw shadows on DND windows .TP -.BI \-b\ daemonize +.BI \-b Daemonize process. .TP .BI \-S @@ -134,9 +137,13 @@ flag is "i" (ignore case). .SH BUGS Please report any you find to https://github.com/chjj/compton. + .SH AUTHORS xcompmgr, originally written by Keith Packard, with contributions from Matthew Allum, Eric Anholt, Dan Doel, Thomas Luebking, Matthew Hawn, Ely Levy, Phil Blundell, and Carl Worth. Compton by Christopher Jeffrey, based on Dana Jansens' original work, with numerous contributions from Richard Grenville. + +.SH SEE ALSO +.BR compton-trans (1) diff --git a/src/compton.c b/src/compton.c index bb9d7bb..fe522f4 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2982,7 +2982,7 @@ usage(void) { " Opacity of window titlebars and borders. (0.1 - 1.0)\n" "-G\n" " Don't draw shadows on DND windows\n" - "-b daemonize\n" + "-b\n" " Daemonize process.\n" "-S\n" " Enable synchronous operation (for debugging).\n" From 1ce58afb1dfd19eb9b213470712300e4b5ccda7d Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Oct 2012 11:56:44 -0500 Subject: [PATCH 5/6] more man page changes --- man/compton-trans.1 | 12 +++++++++ man/compton.1 | 65 ++++++++++++++++++++++++++++++++------------- src/compton.c | 2 +- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/man/compton-trans.1 b/man/compton-trans.1 index 78684a8..97b4d34 100644 --- a/man/compton-trans.1 +++ b/man/compton-trans.1 @@ -1,16 +1,20 @@ .ds q \N'34' .TH compton\-trans 1 + .SH NAME compton\-trans \- an opacity setter tool + .SH SYNOPSIS .nf .B compton-trans [-wncs] [window] -o [opacity] .fi + .SH DESCRIPTION .B compton-trans is a bash script that sets _NET_WM_WINDOW_OPACITY only using standard command-line utilities for X11, including xprop(1) and xwininfo(1). It is similar to other utilities like transset(1) or transset-df(1). + .SH OPTIONS .TP .BI \-w\ window\-id @@ -31,6 +35,7 @@ Specify the new opacity value for the window. This value can be anywhere from 1-100. If it is prefixed with a plus or minus (+/-), this will increment or decrement from the target window's current opacity instead. + .SH EXAMPLES .TP Set window id to opacity of 75%. @@ -47,7 +52,14 @@ compton-trans -s -o 75 .TP Increment current window 5% opacity. compton-trans -c -o +5 + .SH BUGS Please report any you find to https://github.com/chjj/compton. + .SH AUTHORS Christopher Jeffrey (https://github.com/chjj) + +.SH SEE ALSO +.BR compton(1), +.BR xprop(1), +.BR xwininfo(1) diff --git a/man/compton.1 b/man/compton.1 index cdaa234..356b82e 100644 --- a/man/compton.1 +++ b/man/compton.1 @@ -22,6 +22,11 @@ written by Keith Packard). It includes many improvements over the original xcompmgr, including window frame opacity, inactive window transparency, and shadows on argb windows. +.SH EXAMPLE + +$ compton -cC -i 0.6 -e 0.6 -f +$ compton --config ~/compton.conf + .SH OPTIONS .TP .BI \-d\ display @@ -33,19 +38,19 @@ The blur radius for shadows. (default 12) .BI \-o\ opacity The translucency for shadows. (default .75) .TP -.BI \-l\ left-offset +.BI \-l\ left\-offset The left offset for shadows. (default -15) .TP -.BI \-t\ top-offset +.BI \-t\ top\-offset The top offset for shadows. (default -15) .TP -.BI \-I\ fade-in-step +.BI \-I\ fade\-in\-step Opacity change between steps while fading in. (default 0.028) .TP -.BI \-O\ fade-out-step +.BI \-O\ fade\-out\-step Opacity change between steps while fading out. (default 0.03) .TP -.BI \-D\ fade-delta-time +.BI \-D\ fade\-delta\-time The time between steps in a fade in milliseconds. (default 10) .TP .BI \-m\ opacity @@ -77,45 +82,45 @@ Opacity of window titlebars and borders. (0.1 - 1.0) Don't draw shadows on DND windows .TP .BI \-b -Daemonize process. +Daemonize/background process. .TP .BI \-S Enable synchronous operation (for debugging). .TP -.BI \--config\ path +.BI \-\-config\ path Look for configuration file at the path. .TP -.BI \--shadow-red\ value +.BI \-\-shadow\-red\ value Red color value of shadow (0.0 - 1.0, defaults to 0). .TP -.BI \--shadow-green\ value +.BI \-\-shadow\-green\ value Green color value of shadow (0.0 - 1.0, defaults to 0). .TP -.BI \--shadow-blue\ value +.BI \-\-shadow\-blue\ value Blue color value of shadow (0.0 - 1.0, defaults to 0). .TP -.BI \--inactive-opacity-override +.BI \-\-inactive\-opacity\-override Inactive opacity set by -i overrides value of _NET_WM_OPACITY. .TP -.BI \--inactive-dim\ value +.BI \-\-inactive\-dim\ value Dim inactive windows. (0.0 - 1.0, defaults to 0) .TP -.BI \--mark-wmwin-focused +.BI \-\-mark\-wmwin\-focused Try to detect WM windows and mark them as active. .TP -.BI \--shadow-exclude\ condition +.BI \-\-shadow\-exclude\ condition Exclude conditions for shadows. .TP -.BI \--mark-ovredir-focused +.BI \--mark\-ovredir\-focused Mark over-redirect windows as active. .TP -.BI \--no-fading-openclose +.BI \-\-no\-fading\-openclose Do not fade on window open/close. .TP -.BI \--shadow-ignore-shaped +.BI \-\-shadow\-ignore\-shaped Do not paint shadows on shaped windows. .TP -.BI \--detect-rounded-corners +.BI \-\-detect\-rounded\-corners Try to detect windows with rounded corners and don't consider them shaped windows. .TP @@ -135,6 +140,28 @@ flag is "i" (ignore case). is the actual pattern string. +.SH CONFIGURATION +(A more robust sample configuration file exists in the compton +repository.) + +.B Example + +.B ~/compton.conf: + + # Shadows + shadow = true; + + # Opacity + inactive-opacity = 0.8; + frame-opacity = 0.7; + + # Fades + fading = true; + +.B Run with: + + $ compton --config ~/compton.conf + .SH BUGS Please report any you find to https://github.com/chjj/compton. @@ -146,4 +173,4 @@ Compton by Christopher Jeffrey, based on Dana Jansens' original work, with numerous contributions from Richard Grenville. .SH SEE ALSO -.BR compton-trans (1) +.BR compton-trans(1) diff --git a/src/compton.c b/src/compton.c index fe522f4..3fa5996 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2983,7 +2983,7 @@ usage(void) { "-G\n" " Don't draw shadows on DND windows\n" "-b\n" - " Daemonize process.\n" + " Daemonize/background process.\n" "-S\n" " Enable synchronous operation (for debugging).\n" "--config path\n" From 239796abc636e21a58a5607ed4e8f70f8cd85280 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 26 Oct 2012 06:18:49 -0500 Subject: [PATCH 6/6] fix examples in man page. --- man/compton.1 | 1 + 1 file changed, 1 insertion(+) diff --git a/man/compton.1 b/man/compton.1 index 356b82e..56445eb 100644 --- a/man/compton.1 +++ b/man/compton.1 @@ -25,6 +25,7 @@ and shadows on argb windows. .SH EXAMPLE $ compton -cC -i 0.6 -e 0.6 -f + $ compton --config ~/compton.conf .SH OPTIONS