Permalink
Please
sign in to comment.
Showing
with
1,947 additions
and 14 deletions.
- +2 −0 .gitignore
- +16 −10 .travis.yml
- +47 −0 CMakeLists.txt
- +18 −0 CONTRIBUTING.md
- +9 −0 CPPLINT.cfg
- +14 −0 LICENSE
- +111 −0 README.md
- +1 −0 build/.:
- +99 −0 data/xsuspender.conf
- +9 −0 data/xsuspender.desktop
- +327 −0 doc/xsuspender.1
- +19 −0 lint.sh
- +19 −0 src/CMakeLists.txt
- +272 −0 src/config.c
- +42 −0 src/config.h
- +63 −0 src/entry.c
- +36 −0 src/entry.h
- +236 −0 src/events.c
- +20 −0 src/events.h
- +98 −0 src/exec.c
- +12 −0 src/exec.h
- +43 −0 src/macros.h
- 0 src/main.c
- +73 −0 src/rule.c
- +34 −0 src/rule.h
- +283 −0 src/xsuspender.c
- +44 −0 src/xsuspender.h
- +0 −4 xappsuspender.conf
| @@ -0,0 +1,2 @@ | |||
| *build*/* | |||
| !build/.: | |||
| @@ -1,28 +1,34 @@ | |||
| language: python | language: c | ||
| dist: trusty | dist: trusty | ||
| sudo: false | sudo: false | ||
|
|
|
||
| compiler: | |||
| - clang | |||
| - gcc | |||
|
|
|||
| cache: | cache: | ||
| apt: true | apt: true | ||
| pip: true | pip: true | ||
| ccache: true | |||
|
|
|
||
| addons: | addons: | ||
| apt: | apt: | ||
| packages: | packages: | ||
| - python-pip | |||
| - cppcheck | - cppcheck | ||
| - libwnck-dev | - libwnck-3-dev | ||
| - libglib2.0-dev | |||
|
|
|
||
| before_install: | before_install: | ||
| - set -e | - set -e | ||
| - pip install cpplint | - pip install --user cpplint | ||
| - ./lint.sh | |||
|
|
|
||
| install: | install: | ||
| - | - cd build | ||
| - DISPLAY=mock-for-later cmake -DCMAKE_C_FLAGS=-Werror -DCMAKE_INSTALL_PREFIX=~ .. | |||
| - make | |||
| - make install | |||
| - cpack | |||
|
|
|
||
| script: | script: | ||
| - cppcheck --enable=all --error-exitcode=1 -I src src | - xvfb-run make test | ||
| - cpplint --counting=toplevel --linelength=100 --recursive src | |||
|
|
|||
| after_success: | |||
| - | |||
| @@ -0,0 +1,47 @@ | |||
| cmake_minimum_required (VERSION 2.8 FATAL_ERROR) | |||
|
|
|||
| project (xsuspender C) | |||
| set (PROJECT_VERSION 1.0) | |||
|
|
|||
| if (NOT CMAKE_BUILD_TYPE) | |||
| set (CMAKE_BUILD_TYPE Release) | |||
| endif () | |||
|
|
|||
| set (CMAKE_C_STANDARD 99) | |||
| set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") # CMake<=3.0 | |||
|
|
|||
| set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") | |||
| set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -DG_ENABLE_DEBUG") | |||
| set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3") | |||
|
|
|||
| set (example_dir "share/doc/${PROJECT_NAME}/examples") | |||
|
|
|||
| add_definitions (-DPROJECT_NAME="${PROJECT_NAME}" | |||
| -DPROJECT_VERSION="${PROJECT_VERSION}" | |||
| -DEXAMPLE_CONF="${CMAKE_INSTALL_PREFIX}/${example_dir}/${PROJECT_NAME}.conf") | |||
|
|
|||
| install (FILES data/${PROJECT_NAME}.conf | |||
| DESTINATION ${example_dir}) | |||
| install (FILES data/${PROJECT_NAME}.desktop | |||
| DESTINATION etc/xdg/autostart) | |||
| install (FILES man/${PROJECT_NAME}.1 | |||
| DESTINATION man/man1) | |||
|
|
|||
| add_subdirectory (src) | |||
|
|
|||
| # Tests, if X is running | |||
| if (NOT $ENV{DISPLAY} EQUAL "") | |||
| set_property (GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) # Avoid cruft CTest build targets | |||
| include (CTest) | |||
| add_test (TestHelp src/${PROJECT_NAME} --help) | |||
| set_tests_properties (TestHelp PROPERTIES PASS_REGULAR_EXPRESSION "Usage:\n ${PROJECT_NAME}.*") | |||
| endif () | |||
|
|
|||
| # `make package_source` | |||
| set (CPACK_PACKAGE_NAME "${PROJECT_NAME}") | |||
| set (CPACK_PACKAGE_EXECUTABLES "${PROJECT_NAME}") | |||
| set (CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") | |||
| set (CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") | |||
| set (CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;.*build.*;/\\\\..*") | |||
| set (CPACK_SOURCE_GENERATOR "TXZ") | |||
| include (CPack) | |||
| @@ -0,0 +1,18 @@ | |||
| Hacking | |||
| ======= | |||
|
|
|||
| Building | |||
| -------- | |||
|
|
|||
| To enable debugging closer to the metal, compile a debugging-enabled | |||
| binary by passing `-DCMAKE_BUILD_TYPE=Debug` on the cmake line. | |||
|
|
|||
| Running | |||
| ------- | |||
|
|
|||
| Check for leaks with: | |||
|
|
|||
| G_SLICE=always-malloc \ | |||
| G_DEBUG=gc-friendly \ | |||
| G_MESSAGES_DEBUG=all \ | |||
| valgrind --leak-check=full --show-leak-kinds=definite xsuspender | |||
| @@ -0,0 +1,9 @@ | |||
| set noparent | |||
| linelength=100 | |||
| filter=-build/include_subdir | |||
| filter=-build/header_guard | |||
| filter=-legal | |||
| filter=-readability/casting | |||
| filter=-whitespace/parens | |||
| filter=-whitespace/operators | |||
| filter=-whitespace/braces | |||
| @@ -0,0 +1,14 @@ | |||
| DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |||
| Version 2, December 2004 | |||
|
|
|||
| Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> | |||
|
|
|||
| Everyone is permitted to copy and distribute verbatim or modified | |||
| copies of this license document, and changing it is allowed as long | |||
| as the name is changed. | |||
|
|
|||
| DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |||
| TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||
|
|
|||
| 0. You just DO WHAT THE FUCK YOU WANT TO. | |||
|
|
|||
| @@ -0,0 +1,111 @@ | |||
| XSuspender | |||
| ========== | |||
| [](https://travis-ci.org/kernc/xsuspender) | |||
|
|
|||
| Automatically suspend inactive X11 applications. | |||
|
|
|||
| Find a better maintained description here: https://kernc.github.io/xsuspender/ | |||
|
|
|||
| When an application window loses focus, XSuspender tries to match it to | |||
| one of the rules in its configuration. If a match is found, the | |||
| application is sent a SIGSTOP signal (preventing the process from obtaining | |||
| further CPU time). Upon windows regaining focus, the process is seamlessly | |||
| continued where it had left off. | |||
|
|
|||
| #### Advantages | |||
|
|
|||
| * **Reduce battery use (increase battery run-time).** | |||
| Make your laptop run on battery for as long as your mobile phone does, | |||
| using roughly the same technique. | |||
| * **Reduce interaction latency on low-end CPUs.** | |||
| With fewer clients requesting processing power, there's more of it to go | |||
| around where it's needed. | |||
| * **Reduce CPU fan noise.** | |||
| Save the tinnitus for old age. | |||
| * **Avoid apps plotting stuff behind your back.** | |||
| That Kali you're running in a VM is perfectly fine, but god | |||
| only knows what Microsoft Windos is doing. | |||
| * **Suspend processes using well-known Unix signals SIGSTOP & SIGCONT ...** | |||
| ... or custom shell scripts. Decades of portable operating systems | |||
| engineering at its finest. | |||
| * **Preconfigured for recent versions of popular software.** | |||
| Chromium, Firefox, JetBrains IDEs, qBittorrent, VirtualBox ... | |||
|
|
|||
| #### Quirks | |||
|
|
|||
| * Quirky. See [Notes] below. | |||
| * May prevent suspended windows from redrawing until re-gaining focus. | |||
| * May make your web downloads stall and your in-browser media | |||
| playback stop if you configure it thus. | |||
| * Prevents pasting from clipboard while the selection source process | |||
| is suspended | |||
| ([explanation](https://unix.stackexchange.com/questions/316715/xclip-works-differently-in-interactive-and-non-interactive-shells/316890#316890)). | |||
| * Relies on windows having their `_NET_WM_PID` hint set correctly. | |||
| * Won't work in remote X sessions. | |||
| * Won't work with Wayland. | |||
|
|
|||
|
|
|||
| Installation | |||
| ------------ | |||
|
|
|||
| #### From Source | |||
|
|
|||
| ```bash | |||
| # Install build dependencies, namely GLib and Libwnck | |||
| sudo apt install libglib2.0-dev \ | |||
| libwnck-3-dev \ | |||
| make cmake gcc pkg-config | |||
| ``` | |||
|
|
|||
| ```bash | |||
| # Fetch a copy of the source code | |||
| git clone https://github.com/kernc/xsuspender | |||
| cd xsuspender | |||
| # Move to build directory for an out-of-tree build | |||
| cd build | |||
| # Configure and make | |||
| cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. | |||
| make | |||
| make test | |||
| # Install within chosen prefix | |||
| sudo make install | |||
| ``` | |||
|
|
|||
| Usage | |||
| ----- | |||
| For brief usage instructions, run: | |||
|
|
|||
| ```bash | |||
| xsuspender --help | |||
| ``` | |||
|
|
|||
| #### Configuration debugging | |||
|
|
|||
| To have it print verbose debug messages about what it is doing, run the | |||
| program with environmental variable `G_MESSAGES_DEBUG=all` set: | |||
|
|
|||
| G_MESSAGES_DEBUG=all xsuspender | |||
|
|
|||
| This is _strongly recommended_ to confirm your customized configuration | |||
| rules indeed work as you expect. | |||
|
|
|||
| If xsuspender is auto run by your X session manager, you might find clues | |||
| to its unexpected behavior in _~/.xsession-errors_. | |||
|
|
|||
| Notes | |||
| ----- | |||
| [Notes]: #notes | |||
|
|
|||
| * Processes that take a long time to shut down after their window already | |||
| disappears may be stopped in the middle of their termination routines. | |||
| Avoid with reasonably generous `suspend_delay`. | |||
| * Windows that minimize to system tray need to be awaken frequently to | |||
| respond to click events in a seamless manner. | |||
| * Don't configure xsuspender for software you want to keep continuously alive | |||
| in the background, such as music players, daemons, IM clients ... If you | |||
| frequently stream music from YouTube, you might give [Musictube] a try. | |||
|
|
|||
| [Musictube]: https://flavio.tordini.org/musictube | |||
| @@ -0,0 +1 @@ | |||
| I'll just leave this here. | |||
| @@ -0,0 +1,99 @@ | |||
| # Configuration file for xsuspender. | |||
| # | |||
| # Sections represent rules windows are matched with. | |||
| # Find full documentation in xsuspender(1) manual. | |||
| # | |||
| # [Example] | |||
| # # Window matching rules. Some can be left blank. | |||
| # # Intersection of non-blanks applies. | |||
| # match_wm_class_contains = SomeApplication | |||
| # match_wm_class_group_contains = ... | |||
| # match_wm_name_contains = Part of Some Window Title | |||
| # | |||
| # # Seconds to wait before suspending after window loses focus. | |||
| # suspend_delay = 10 | |||
| # | |||
| # # Resume suspended process every this many seconds … | |||
| # resume_every = 50 | |||
| # | |||
| # # … for this many seconds. | |||
| # resume_for = 5 | |||
| # | |||
| # # Before suspending, execute this shell script. If it fails, | |||
| # # abort suspension. | |||
| # exec_suspend = echo "suspending window $XID of process $PID" | |||
| # | |||
| # # Before resuming, execute this shell script. Resume the | |||
| # # process regardless script failure. | |||
| # exec_resume = echo resuming ... | |||
| # | |||
| # # Whether to send SIGSTOP / SIGCONT signals or not. If false, | |||
| # # just the exec_* scripts are run. | |||
| # send_signals = true | |||
| # | |||
| # # Also suspend descendant processes that match this regex. | |||
| # suspend_subtree_pattern = . | |||
| # | |||
| # # Whether to apply the rule only when on battery power. | |||
| # only_on_battery = true | |||
| # | |||
| # # Whether to auto-apply rules when switching to battery | |||
| # # power even if the window(s) didn't just lose focus. | |||
| # auto_suspend_on_battery = true | |||
| # | |||
| # | |||
| # Values set in the Default section are inherited and overridden | |||
| # by other sections below. | |||
|
|
|||
| [Default] | |||
| suspend_delay = 5 | |||
| resume_every = 50 | |||
| resume_for = 5 | |||
| send_signals = true | |||
| only_on_battery = true | |||
| auto_suspend_on_battery = true | |||
|
|
|||
| # Preset configuration for some common software. | |||
|
|
|||
| [Chromium] | |||
| suspend_delay = 10 | |||
| match_wm_class_contains = chromium | |||
| suspend_subtree_pattern = chromium | |||
|
|
|||
| [Firefox] | |||
| suspend_delay = 10 | |||
| match_wm_class_contains = Navigator | |||
| match_wm_class_group_contains = Firefox | |||
| suspend_subtree_pattern = \/(firefox|plugin-container) | |||
|
|
|||
| [JetBrains IDEs] | |||
| match_wm_class_group_contains = jetbrains- | |||
|
|
|||
| [VirtualBox] | |||
| match_wm_class_contains = VirtualBox | |||
| match_wm_name_contains = - Oracle VM | |||
| exec_suspend = VBoxManage controlvm "$(ps -o args= -q $PID | sed -E 's/.*--startvm ([^ ]+).*/\1/')" pause | |||
| exec_resume = VBoxManage controlvm "$(ps -o args= -q $PID | sed -E 's/.*--startvm ([^ ]+).*/\1/')" resume | |||
| send_signals = false | |||
| resume_every = 0 | |||
| only_on_battery = false | |||
|
|
|||
| [qBittorrent] | |||
| match_wm_class_contains = qbittorrent | |||
| resume_every = 5 | |||
| resume_for = 1 | |||
| suspend_delay = 60 | |||
|
|
|||
| #[MyApplication] | |||
| #match_wm_name_contains = | |||
| #match_wm_class_contains = | |||
| #match_wm_class_group_contains = | |||
| #suspend_delay = 10 | |||
| #resume_every = 50 | |||
| #resume_for = 5 | |||
| #exec_suspend = | |||
| #exec_resume = | |||
| #suspend_subtree_pattern = | |||
| #send_signals = true | |||
| #only_on_battery = true | |||
| #auto_suspend_on_battery = true | |||
| @@ -0,0 +1,9 @@ | |||
| [Desktop Entry] | |||
| Type=Application | |||
| Name=XSuspender | |||
| Comment=Automatically suspend inactive windows | |||
| TryExec=xsuspender | |||
| Exec=xsuspender | |||
| Icon=preferences-system-windows | |||
| NoDisplay=false | |||
| Hidden=true | |||
Oops, something went wrong.
0 comments on commit
5fe8ce1