diff --git a/.github/scripts/docker-build.bash b/.github/scripts/docker-build.bash new file mode 100755 index 000000000..153fcf2cd --- /dev/null +++ b/.github/scripts/docker-build.bash @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -ex + +DOCKERHUB_IMAGE_ID=$DOCKERHUB_ACCOUNT/$IMAGE_NAME + +# Change all uppercase to lowercase +DOCKERHUB_IMAGE_ID=$(echo $DOCKERHUB_IMAGE_ID | tr '[A-Z]' '[a-z]') + +image_tags=() + +# Strip git ref prefix from version +VERSION_TAG=$(echo $GITHUB_REF | sed -e 's,.*/\(.*\),\1,') + +# Strip "v" prefix from tag name +if [[ "$GITHUB_REF" == refs/tags/* ]]; then + VERSION_TAG=$(echo $VERSION_TAG | sed -e 's/^v//') +fi + +image_tags+=("--tag" "$DOCKERHUB_IMAGE_ID:$VERSION_TAG") + +# tag as latest on releases +if [[ "$RELEASE" == ON ]]; then + image_tags+=("--tag" "$DOCKERHUB_IMAGE_ID:latest") +fi + +# Only build amd64 on PRs, build all platforms on main. The arm builds +# take far too long. +image_platforms="--platform linux/amd64" +push_image="" +cache_tag="pr-cache" + +# Only push on main +if [[ "$GITHUB_REF" == refs/heads/main ]]; then + push_image="--push" + image_platforms="--platform linux/arm/v7,linux/arm64/v8,linux/amd64" + cache_tag="main-cache" +fi + +docker buildx build \ + ${push_image} \ + ${image_platforms} \ + --cache-from=type=registry,ref=$DOCKERHUB_ACCOUNT/$IMAGE_NAME:$cache_tag \ + --cache-to=type=registry,ref=$DOCKERHUB_ACCOUNT/$IMAGE_NAME:$cache_tag,mode=max \ + "${image_tags[@]}" \ + . diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index a6a7fcae4..3c4945bfe 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -2,7 +2,13 @@ name: Docker on: push: - # Publish `main` as Docker `latest` image. + branches: + - main + paths-ignore: + - web/** + - doc/** + + pull_request: branches: - main paths-ignore: @@ -23,7 +29,7 @@ env: DOCKER_BUILDKIT: 1 jobs: - buildx: + docker-buildx: runs-on: ubuntu-latest steps: - name: Checkout @@ -35,26 +41,8 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Log into Dockerhub registry run: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u $DOCKERHUB_ACCOUNT --password-stdin - - name: Build - run: | - DOCKERHUB_IMAGE_ID=$DOCKERHUB_ACCOUNT/$IMAGE_NAME - - # Change all uppercase to lowercase - DOCKERHUB_IMAGE_ID=$(echo $DOCKERHUB_IMAGE_ID | tr '[A-Z]' '[a-z]') - - # Strip git ref prefix from version - VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') - - # Strip "v" prefix from tag name - [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') - - # Use Docker `latest` tag convention - [ "$VERSION" == "main" ] && VERSION=latest - - docker buildx build \ - --push \ - --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \ - --cache-from=type=registry,ref=$DOCKERHUB_ACCOUNT/$IMAGE_NAME:buildcache \ - --cache-to=type=registry,ref=$DOCKERHUB_ACCOUNT/$IMAGE_NAME:buildcache,mode=max \ - --tag $DOCKERHUB_IMAGE_ID:$VERSION \ - . + - name: Build and push Docker image + env: + RELEASE: "${{ startsWith(github.ref, 'refs/tags/') && 'ON' || 'OFF' }}" + GITHUB_REF: ${{ github.ref }} + run: ./.github/scripts/docker-build.bash diff --git a/.github/workflows/publish-appimage.yml b/.github/workflows/publish-appimage.yml index 4edeb26a9..6215f01c3 100644 --- a/.github/workflows/publish-appimage.yml +++ b/.github/workflows/publish-appimage.yml @@ -80,9 +80,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Get git version - id: git-version - run: echo "GIT_VERSION=$(git describe --tags --always --debug)" | tee -a $GITHUB_ENV - name: Import GPG Deploy Key # only run on main branch if: github.ref == 'refs/heads/main' @@ -109,19 +106,21 @@ jobs: env: RELEASE: "${{ startsWith(github.ref, 'refs/tags/') && 'ON' || 'OFF' }}" - run: ./conky-x86_64.AppImage --version # print version - - run: mv conky-x86_64.AppImage conky-${{ matrix.os }}-${{ matrix.arch }}-${{ env.GIT_VERSION }}.AppImage - - run: mv conky-x86_64.AppImage.sha256 conky-${{ matrix.os }}-${{ matrix.arch }}-${{ env.GIT_VERSION }}.AppImage.sha256 + - name: Set CONKY_VERSION + run: echo "CONKY_VERSION=$(./conky-x86_64.AppImage --short-version)" | tee -a $GITHUB_ENV + - run: mv conky-x86_64.AppImage conky-${{ matrix.os }}-${{ matrix.arch }}-v${{ env.CONKY_VERSION }}.AppImage + - run: mv conky-x86_64.AppImage.sha256 conky-${{ matrix.os }}-${{ matrix.arch }}-v${{ env.CONKY_VERSION }}.AppImage.sha256 - name: Upload AppImage artifact uses: actions/upload-artifact@v4 with: - path: 'conky-${{ matrix.os }}-${{ matrix.arch }}-${{ env.GIT_VERSION }}.AppImage' - name: 'conky-${{ matrix.os }}-${{ matrix.arch }}-${{ env.GIT_VERSION }}.AppImage' + path: 'conky-${{ matrix.os }}-${{ matrix.arch }}-v${{ env.CONKY_VERSION }}.AppImage' + name: 'conky-${{ matrix.os }}-${{ matrix.arch }}-v${{ env.CONKY_VERSION }}.AppImage' if-no-files-found: error - name: Upload AppImage checksum artifact uses: actions/upload-artifact@v4 with: - path: 'conky-${{ matrix.os }}-${{ matrix.arch }}-${{ env.GIT_VERSION }}.AppImage.sha256' - name: 'conky-${{ matrix.os }}-${{ matrix.arch }}-${{ env.GIT_VERSION }}.AppImage.sha256' + path: 'conky-${{ matrix.os }}-${{ matrix.arch }}-v${{ env.CONKY_VERSION }}.AppImage.sha256' + name: 'conky-${{ matrix.os }}-${{ matrix.arch }}-v${{ env.CONKY_VERSION }}.AppImage.sha256' if-no-files-found: error - name: Upload man page artifact uses: actions/upload-artifact@v4 diff --git a/Dockerfile b/Dockerfile index 46a17ea18..8be2d3d18 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy AS builder +FROM ubuntu:noble AS builder RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive \ @@ -6,6 +6,7 @@ RUN apt-get update \ audacious-dev \ ca-certificates \ clang \ + cmake \ curl \ gfortran \ git \ @@ -39,25 +40,11 @@ RUN apt-get update \ libxml2-dev \ libxmmsclient-dev \ libxnvctrl-dev \ - make \ ninja-build \ patch \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -# Compile CMake, we need the latest because the bug here (for armv7 builds): -# https://gitlab.kitware.com/cmake/cmake/-/issues/20568 -WORKDIR /cmake -ENV CMAKE_VERSION 3.25.1 -RUN curl -Lq https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz -o cmake-${CMAKE_VERSION}.tar.gz \ - && tar xf cmake-${CMAKE_VERSION}.tar.gz \ - && cd cmake-${CMAKE_VERSION} \ - && CC=clang CXX=clang++ CFLAGS="-D_FILE_OFFSET_BITS=64" CXXFLAGS="-D_FILE_OFFSET_BITS=64" ./bootstrap --system-libs --parallel=5 \ - && make -j5 \ - && make -j5 install \ - && cd \ - && rm -rf /cmake - COPY . /conky WORKDIR /conky/build @@ -112,7 +99,7 @@ RUN sh -c 'if [ "$X11" = "yes" ] ; then \ && cmake --build . \ && cmake --install . -FROM ubuntu:jammy +FROM ubuntu:noble RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive \ @@ -121,14 +108,14 @@ RUN apt-get update \ libc++1 \ libc++abi1 \ libcairo2 \ - libcurl4 \ + libcurl4t64 \ libdbus-glib-1-2 \ - libical3 \ - libimlib2 \ + libical3t64 \ + libimlib2t64 \ libircclient1 \ - libiw30 \ + libiw30t64 \ liblua5.3-0 \ - libmicrohttpd12 \ + libmicrohttpd12t64 \ libmysqlclient21 \ libncurses6 \ libpulse0 \ @@ -140,6 +127,7 @@ RUN apt-get update \ libxext6 \ libxfixes3 \ libxft2 \ + libxi6 \ libxinerama1 \ libxml2 \ libxmmsclient6 \ diff --git a/cmake/Conky.cmake b/cmake/Conky.cmake index f49a19633..b84299af0 100644 --- a/cmake/Conky.cmake +++ b/cmake/Conky.cmake @@ -132,8 +132,8 @@ endif(OS_HAIKU) # Do version stuff set(VERSION_MAJOR "1") -set(VERSION_MINOR "20") -set(VERSION_PATCH "3") +set(VERSION_MINOR "21") +set(VERSION_PATCH "0") find_program(APP_AWK awk) @@ -153,12 +153,6 @@ if(NOT APP_UNAME) message(FATAL_ERROR "Unable to find program 'uname'") endif(NOT APP_UNAME) -find_program(APP_GPERF gperf) - -if(NOT APP_GPERF) - message(FATAL_ERROR "Unable to find program 'gperf' (required at build-time as of Conky v1.20.2)") -endif(NOT APP_GPERF) - if(NOT RELEASE) find_program(APP_GIT git) @@ -169,18 +163,24 @@ if(NOT RELEASE) mark_as_advanced(APP_GIT) endif(NOT RELEASE) -mark_as_advanced(APP_AWK APP_WC APP_UNAME APP_GPERF) +mark_as_advanced(APP_AWK APP_WC APP_UNAME) execute_process(COMMAND ${APP_UNAME} -sm RESULT_VARIABLE RETVAL OUTPUT_VARIABLE BUILD_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process(COMMAND ${APP_GIT} rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE RETVAL + OUTPUT_VARIABLE GIT_SHORT_SHA + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(RELEASE) set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") else(RELEASE) set(VERSION - "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}_pre${COMMIT_COUNT}") + "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-pre-${GIT_SHORT_SHA}") endif(RELEASE) set(COPYRIGHT "Copyright Brenden Matthews, et al, 2005-2024") diff --git a/cmake/ConkyBuildOptions.cmake b/cmake/ConkyBuildOptions.cmake index 6fb3ec042..fe4384dac 100644 --- a/cmake/ConkyBuildOptions.cmake +++ b/cmake/ConkyBuildOptions.cmake @@ -67,6 +67,8 @@ option(BUILD_EXTRAS "Build extras (includes syntax files for editors)" false) option(BUILD_I18N "Enable if you want internationalization support" true) +option(BUILD_COLOUR_NAME_MAP "Include mappings of colour name -> RGB (i.e., red -> ff0000)" true) + if(BUILD_I18N) set(LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/share/locale" CACHE STRING "Directory containing the locales") diff --git a/cmake/ConkyPlatformChecks.cmake b/cmake/ConkyPlatformChecks.cmake index bb314c85b..1de7c7528 100644 --- a/cmake/ConkyPlatformChecks.cmake +++ b/cmake/ConkyPlatformChecks.cmake @@ -509,7 +509,7 @@ if(BUILD_LUA_CAIRO) set(luacairo_libs ${CAIROXLIB_LIBRARIES} ${luacairo_libs}) set(luacairo_includes ${CAIROXLIB_INCLUDE_DIRS} ${luacairo_includes}) endif(BUILD_LUA_CAIRO_XLIB) - + find_program(APP_PATCH patch) if(NOT APP_PATCH) @@ -668,6 +668,16 @@ if(BUILD_DOCS OR BUILD_EXTRAS) endif() endif(BUILD_DOCS OR BUILD_EXTRAS) +if(BUILD_COLOUR_NAME_MAP) + find_program(APP_GPERF gperf) + + if(NOT APP_GPERF) + message(FATAL_ERROR "Unable to find program 'gperf' (required at build-time as of Conky v1.20.2)") + endif(NOT APP_GPERF) + + mark_as_advanced(APP_GPERF) +endif(BUILD_COLOUR_NAME_MAP) + if(CMAKE_BUILD_TYPE MATCHES "Debug") set(DEBUG true) endif(CMAKE_BUILD_TYPE MATCHES "Debug") diff --git a/cmake/config.h.in b/cmake/config.h.in index 7efa46418..5eeff2076 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -142,6 +142,8 @@ #cmakedefine BUILD_HSV_GRADIENT 1 +#cmakedefine BUILD_COLOUR_NAME_MAP 1 + #cmakedefine HAVE_STATFS64 1 #ifndef HAVE_STATFS64 #define statfs64 statfs diff --git a/flake.lock b/flake.lock index 69e2cc446..6fb25794b 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1709126324, - "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1709703039, - "narHash": "sha256-6hqgQ8OK6gsMu1VtcGKBxKQInRLHtzulDo9Z5jxHEFY=", + "lastModified": 1714253743, + "narHash": "sha256-mdTQw2XlariysyScCv2tTE45QSU9v/ezLcHJ22f0Nxc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "9df3e30ce24fd28c7b3e2de0d986769db5d6225d", + "rev": "58a1abdbae3217ca6b702f03d3b35125d88a2994", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index e6f5c8098..0da4eb9a7 100644 --- a/flake.nix +++ b/flake.nix @@ -30,20 +30,25 @@ default = conky; }; - apps.conky = flake-utils.lib.mkApp {drv = packages.conky;}; - apps.default = apps.conky; - devShells.default = mkShell { - buildInputs = - packages.conky.buildInputs - ++ packages.conky.nativeBuildInputs - ++ [ - alejandra # for beautifying flake - lefthook # for git hooks - nodejs # for web/ stuff - # for docs - (python3.withPackages (ps: with ps; [jinja2])) - ]; + apps.conky = flake-utils.lib.mkApp { + drv = packages.conky; }; + apps.default = apps.conky; + devShells.default = + mkShell.override { + stdenv = llvmPackages_18.libcxxStdenv; + } rec { + buildInputs = + packages.conky.buildInputs + ++ packages.conky.nativeBuildInputs + ++ [ + alejandra # for beautifying flake + lefthook # for git hooks + nodejs # for web/ stuff + # for docs + (python3.withPackages (ps: with ps; [jinja2])) + ]; + }; } ) // { @@ -53,20 +58,21 @@ name = "conky"; src = ./.; cmakeFlags = [ + "-DBUILD_CURL=ON" + "-DBUILD_LUA_CAIRO_XLIB=ON" "-DBUILD_LUA_CAIRO=ON" "-DBUILD_LUA_IMLIB2=ON" "-DBUILD_LUA_RSVG=ON" "-DBUILD_RSS=ON" - "-DBUILD_CURL=ON" ]; nativeBuildInputs = [ - clang_16 + clang_18 cmake git - llvmPackages_16.clang-unwrapped + gperf + llvmPackages_18.clang-unwrapped ninja pkg-config - gperf ]; buildInputs = [ @@ -77,8 +83,7 @@ imlib2 librsvg libxml2 - llvmPackages_16.libcxx - llvmPackages_16.libcxxabi + llvmPackages_18.libcxx lua5_4 ncurses xorg.libICE diff --git a/lua/CMakeLists.txt b/lua/CMakeLists.txt index fb96ee0cd..19b02a5a1 100644 --- a/lua/CMakeLists.txt +++ b/lua/CMakeLists.txt @@ -24,7 +24,6 @@ add_definitions(-DTOLUA_RELEASE) # NOTE: Don't chain options in IFs here, their dependency is already handled by # ConkyBuildOptions.cmake - if(BUILD_LUA_CAIRO) include_directories(${luacairo_includes} ${CMAKE_CURRENT_SOURCE_DIR}) @@ -32,7 +31,7 @@ if(BUILD_LUA_CAIRO) # better solution, please let me know wrap_tolua(luacairo_src cairo.pkg libcairo.patch) - add_library(conky-cairo SHARED ${luacairo_src}) + add_library(conky-cairo MODULE ${luacairo_src}) set_target_properties(conky-cairo PROPERTIES OUTPUT_NAME "cairo") target_link_libraries(conky-cairo ${luacairo_libs} toluapp_lib_static) @@ -70,7 +69,7 @@ if(BUILD_LUA_IMLIB2) wrap_tolua(luaimlib2_src imlib2_old.pkg) endif(IMLIB2_VERSION VERSION_GREATER_EQUAL "1.10.0") - add_library(conky-imlib2 SHARED ${luaimlib2_src}) + add_library(conky-imlib2 MODULE ${luaimlib2_src}) set_target_properties(conky-imlib2 PROPERTIES OUTPUT_NAME "imlib2") target_link_libraries(conky-imlib2 ${luaimlib2_libs} toluapp_lib_static) @@ -84,7 +83,7 @@ if(BUILD_LUA_CAIRO AND BUILD_LUA_IMLIB2) ${CMAKE_CURRENT_SOURCE_DIR}) wrap_tolua(luacairo_imlib2_helper_src cairo_imlib2_helper.pkg) - add_library(conky-cairo_imlib2_helper SHARED ${luacairo_imlib2_helper_src}) + add_library(conky-cairo_imlib2_helper MODULE ${luacairo_imlib2_helper_src}) set_target_properties(conky-cairo_imlib2_helper PROPERTIES OUTPUT_NAME "cairo_imlib2_helper") @@ -99,7 +98,7 @@ if(BUILD_LUA_RSVG) include_directories(${luarsvg_includes} ${CMAKE_CURRENT_SOURCE_DIR}) wrap_tolua(luarsvg_src rsvg.pkg) - add_library(conky-rsvg SHARED ${luarsvg_src}) + add_library(conky-rsvg MODULE ${luarsvg_src}) set_target_properties(conky-rsvg PROPERTIES OUTPUT_NAME "rsvg") target_link_libraries(conky-rsvg ${luarsvg_libs} toluapp_lib_static) diff --git a/src/colour-names-stub.hh b/src/colour-names-stub.hh new file mode 100644 index 000000000..7008d0765 --- /dev/null +++ b/src/colour-names-stub.hh @@ -0,0 +1,28 @@ +/* + * To generate colour-names.hh, you must have gperf installed during build. + * This is a dummy implementation for builds without gperf. + * Color name matching will always return null (i.e. no match). + */ + +#pragma once + +#include + +#include "logging.h" + +struct rgb { + const char *name; + uint8_t red; + uint8_t green; + uint8_t blue; +}; + +class color_name_hash { + public: + static const struct rgb *in_word_set(const char *str, size_t len); +}; + +const struct rgb *color_name_hash::in_word_set(const char *str, size_t len) { + DBGP2("color parsing not supported"); + return nullptr; +} diff --git a/src/colours.cc b/src/colours.cc index 7e5641c9e..9adc9bf91 100644 --- a/src/colours.cc +++ b/src/colours.cc @@ -42,6 +42,7 @@ Colour Colour::from_argb32(uint32_t argb) { return out; } +#ifdef BUILD_COLOUR_NAME_MAP #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wregister" #pragma GCC diagnostic push @@ -49,6 +50,9 @@ Colour Colour::from_argb32(uint32_t argb) { #include #pragma clang diagnostic pop #pragma GCC diagnostic pop +#else /* BUILD_COLOUR_NAME_MAP */ +#include "colour-names-stub.hh" +#endif /* BUILD_COLOUR_NAME_MAP */ std::optional parse_color_name(const std::string &name) { const rgb *value = color_name_hash::in_word_set(name.c_str(), name.length()); diff --git a/src/conky.cc b/src/conky.cc index 327f3f596..a49ec4c85 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -2101,9 +2101,9 @@ const char *getopt_string = ; const struct option longopts[] = { - {"help", 0, nullptr, 'h'}, {"version", 0, nullptr, 'V'}, - {"quiet", 0, nullptr, 'q'}, {"debug", 0, nullptr, 'D'}, - {"config", 1, nullptr, 'c'}, + {"help", 0, nullptr, 'h'}, {"version", 0, nullptr, 'v'}, + {"short-version", 0, nullptr, 'V'}, {"quiet", 0, nullptr, 'q'}, + {"debug", 0, nullptr, 'D'}, {"config", 1, nullptr, 'c'}, #ifdef BUILD_BUILTIN_CONFIG {"print-config", 0, nullptr, 'C'}, #endif diff --git a/src/display-x11.cc b/src/display-x11.cc index 47105bf8f..5a0d38062 100644 --- a/src/display-x11.cc +++ b/src/display-x11.cc @@ -49,6 +49,7 @@ #include #undef COUNT #endif /* BUILD_XINPUT */ +#include #include #include @@ -81,9 +82,7 @@ extern int need_to_update; int get_border_total(); extern conky::range_config_setting maximum_width; extern Colour current_color; -#ifdef BUILD_XFT -static int xft_dpi = -1; -#endif /* BUILD_XFT */ +static float screen_dpi = -1; /* for x_fonts */ struct x_font_list { @@ -147,16 +146,36 @@ struct _x11_stuff_s { #endif } x11_stuff; +void update_dpi() { + // Add XRandR support if used + // See dunst PR: https://github.com/dunst-project/dunst/pull/608 + +#ifdef BUILD_XFT + if (screen_dpi > 0) return; + if (use_xft.get(*state)) { + XrmDatabase db = XrmGetDatabase(display); + if (db != nullptr) { + char *xrmType; + XrmValue xrmValue; + if (XrmGetResource(db, "Xft.dpi", "Xft.dpi", &xrmType, &xrmValue)) { + screen_dpi = strtof(xrmValue.addr, NULL); + } + } else { + auto dpi = XGetDefault(display, "Xft", "dpi"); + if (dpi) { screen_dpi = strtof(dpi, nullptr); } + } + } +#endif /* BUILD_XFT */ + if (screen_dpi > 0) return; + screen_dpi = static_cast(DisplayWidth(display, screen)) * 25.4 / + static_cast(DisplayWidthMM(display, screen)); +} + static void X11_create_window() { if (!window.window) { return; } setup_fonts(); load_fonts(utf8_mode.get(*state)); -#ifdef BUILD_XFT - if (use_xft.get(*state)) { - auto dpi = XGetDefault(display, "Xft", "dpi"); - if (dpi) { xft_dpi = strtol(dpi, nullptr, 10); } - } -#endif /* BUILD_XFT */ + update_dpi(); update_text_area(); /* to position text/window on screen */ #ifdef OWN_WINDOW @@ -713,19 +732,31 @@ bool handle_event( get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom); } -#ifdef USE_ARGB - if (have_argb_visual) return true; -#endif + if (ev.xproperty.atom == 0) return false; - if (ev.xproperty.atom == ATOM(_XROOTPMAP_ID) || - ev.xproperty.atom == ATOM(_XROOTMAP_ID)) { - if (forced_redraw.get(*state)) { - draw_stuff(); - next_update_time = get_time(); - need_to_update = 1; + if (ev.xproperty.atom == XA_RESOURCE_MANAGER) { + update_x11_resource_db(); + update_x11_workarea(); + screen_dpi = -1; + update_dpi(); + return true; + } + + if (!have_argb_visual) { + Atom _XROOTPMAP_ID = XInternAtom(display, "_XROOTPMAP_ID", True); + Atom _XROOTMAP_ID = XInternAtom(display, "_XROOTMAP_ID", True); + if (ev.xproperty.atom == _XROOTPMAP_ID || + ev.xproperty.atom == _XROOTMAP_ID) { + if (forced_redraw.get(*state)) { + draw_stuff(); + next_update_time = get_time(); + need_to_update = 1; + } + return true; } } - return true; + + return false; } template <> @@ -947,11 +978,9 @@ void display_output_x11::move_win(int x, int y) { const float PIXELS_PER_INCH = 96.0; float display_output_x11::get_dpi_scale() { -#ifdef BUILD_XFT - if (use_xft.get(*state) && xft_dpi > 0) { - return static_cast(xft_dpi) / PIXELS_PER_INCH; + if (screen_dpi > 0) { + return static_cast(screen_dpi) / PIXELS_PER_INCH; } -#endif /* BUILD_XFT */ return 1.0; } diff --git a/src/gui.cc b/src/gui.cc index 5e6d242e2..f7c1d8a04 100644 --- a/src/gui.cc +++ b/src/gui.cc @@ -45,8 +45,6 @@ #endif /* basic display attributes */ -int display_width; -int display_height; int screen; /* workarea where window / text is aligned (from _NET_WORKAREA on X11) */ diff --git a/src/gui.h b/src/gui.h index 8b68fe42c..65499763d 100644 --- a/src/gui.h +++ b/src/gui.h @@ -168,8 +168,6 @@ inline bool TEST_HINT(uint16_t mask, window_hints hint) { #ifdef BUILD_X11 extern Display *display; #endif /* BUILD_X11 */ -extern int display_width; -extern int display_height; extern int screen; extern int workarea[4]; diff --git a/src/main.cc b/src/main.cc index 1dd37e283..4b9ca4bcd 100644 --- a/src/main.cc +++ b/src/main.cc @@ -57,6 +57,8 @@ #endif /* BUILD_OLD_CONFIG */ #endif /* BUILD_BUILTIN_CONFIG */ +static void print_short_version() { std::cout << VERSION << std::endl; } + static void print_version() { std::cout << _(PACKAGE_NAME " " VERSION " compiled for " BUILD_ARCH "\n" @@ -233,7 +235,8 @@ static void print_help(const char *prog_name) { "window. Command line options will override configurations defined in " "config\n" "file.\n" - " -v, --version version\n" + " -v, --version version with build details\n" + " -V, --short-version short version\n" " -q, --quiet quiet mode\n" " -D, --debug increase debugging output, ie. -DD for " "more debugging\n" @@ -321,9 +324,11 @@ int main(int argc, char **argv) { global_debug_level++; break; case 'v': - case 'V': print_version(); return EXIT_SUCCESS; + case 'V': + print_short_version(); + return EXIT_SUCCESS; case 'c': current_config = optarg; break; diff --git a/src/update-cb.cc b/src/update-cb.cc index b6ebe6ce7..2096ea23c 100644 --- a/src/update-cb.cc +++ b/src/update-cb.cc @@ -140,7 +140,7 @@ void run_all_callbacks() { if (cb.remaining-- == 0) { /* run the callback as long as someone holds a pointer to it; * if no one owns the callback, run it at most UNUSED_MAX times */ - if (!i->unique() || ++cb.unused < UNUSED_MAX) { + if (i->use_count() > 1 || ++cb.unused < UNUSED_MAX) { cb.remaining = cb.period - 1; cb.run(); if (cb.wait) { ++wait; } diff --git a/src/x11.cc b/src/x11.cc index 778d7e692..ebf2d92d5 100644 --- a/src/x11.cc +++ b/src/x11.cc @@ -90,6 +90,7 @@ extern "C" { #include #include #endif +#include } /* some basic X11 stuff */ @@ -106,9 +107,8 @@ struct conky_x11_window window; bool have_argb_visual = false; /* local prototypes */ -static void update_workarea(); static Window find_desktop_window(Window *p_root, Window *p_desktop); -static Window find_subwindow(Window win, int w, int h); +static Window find_desktop_window_impl(Window win, int w, int h); /* WARNING, this type not in Xlib spec */ static int x11_error_handler(Display *d, XErrorEvent *err) { @@ -260,12 +260,14 @@ void init_x11() { info.x11.desktop.name.clear(); screen = DefaultScreen(display); - display_width = DisplayWidth(display, screen); - display_height = DisplayHeight(display, screen); - get_x11_desktop_info(display, 0); + XSetErrorHandler(&x11_error_handler); + XSetIOErrorHandler(&x11_ioerror_handler); - update_workarea(); + update_x11_resource_db(true); + update_x11_workarea(); + + get_x11_desktop_info(display, 0); #ifdef HAVE_XCB_ERRORS auto connection = xcb_connect(NULL, NULL); @@ -275,11 +277,6 @@ void init_x11() { } } #endif /* HAVE_XCB_ERRORS */ - - /* WARNING, this type not in Xlib spec */ - XSetErrorHandler(&x11_error_handler); - XSetIOErrorHandler(&x11_ioerror_handler); - DBGP("leave init_x11()"); } @@ -291,12 +288,39 @@ void deinit_x11() { } } -static void update_workarea() { +// Source: dunst +// https://github.com/bebehei/dunst/blob/1bc3237a359f37905426012c0cca90d71c4b3b18/src/x11/x.c#L463 +void update_x11_resource_db(bool first_run) { + XrmDatabase db; + XTextProperty prop; + Window root; + + XFlush(display); + + root = RootWindow(display, screen); + + XLockDisplay(display); + if (XGetTextProperty(display, root, &prop, XA_RESOURCE_MANAGER)) { + if (!first_run) { + db = XrmGetDatabase(display); + XrmDestroyDatabase(db); + } + + db = XrmGetStringDatabase((const char *)prop.value); + XrmSetDatabase(display, db); + } + XUnlockDisplay(display); + + XFlush(display); + XSync(display, false); +} + +void update_x11_workarea() { /* default work area is display */ workarea[0] = 0; workarea[1] = 0; - workarea[2] = display_width; - workarea[3] = display_height; + workarea[2] = DisplayWidth(display, screen); + workarea[3] = DisplayHeight(display, screen); #ifdef BUILD_XINERAMA /* if xinerama is being used, adjust workarea to the head's area */ @@ -344,9 +368,12 @@ static Window find_desktop_window(Window root) { Window desktop = root; /* get subwindows from root */ - desktop = find_subwindow(root, -1, -1); - update_workarea(); - desktop = find_subwindow(desktop, workarea[2], workarea[3]); + int display_width = DisplayWidth(display, screen); + int display_height = DisplayHeight(display, screen); + desktop = find_desktop_window_impl(root, display_width, display_height); + update_x11_workarea(); + desktop = find_desktop_window_impl(desktop, workarea[2] - workarea[0], + workarea[3] - workarea[1]); if (desktop != root) { NORM_ERR("desktop window (0x%lx) is subwindow of root window (0x%lx)", @@ -514,13 +541,11 @@ void x11_init_window(lua::state &l, bool own) { 0, 0}; flags |= CWBackPixel; -#ifdef BUILD_ARGB if (have_argb_visual) { attrs.colormap = window.colourmap; flags &= ~CWBackPixel; flags |= CWBorderPixel | CWColormap; } -#endif /* BUILD_ARGB */ /* Parent is desktop window (which might be a child of root) */ window.window = @@ -557,13 +582,11 @@ void x11_init_window(lua::state &l, bool own) { Atom xa; flags |= CWBackPixel; -#ifdef BUILD_ARGB if (have_argb_visual) { attrs.colormap = window.colourmap; flags &= ~CWBackPixel; flags |= CWBorderPixel | CWColormap; } -#endif /* BUILD_ARGB */ if (own_window_type.get(l) == window_type::DOCK) { window.x = window.y = 0; @@ -868,7 +891,7 @@ void x11_init_window(lua::state &l, bool own) { DBGP("leave x11_init_window()"); } -static Window find_subwindow(Window win, int w, int h) { +static Window find_desktop_window_impl(Window win, int w, int h) { unsigned int i, j; Window troot, parent, *children; unsigned int n; @@ -880,13 +903,11 @@ static Window find_subwindow(Window win, int w, int h) { for (j = 0; j < n; j++) { XWindowAttributes attrs; - if (XGetWindowAttributes(display, children[j], &attrs) != 0) { /* Window must be mapped and same size as display or * work space */ - if (attrs.map_state != 0 && - ((attrs.width == display_width && attrs.height == display_height) || - (attrs.width == w && attrs.height == h))) { + if (attrs.map_state == IsViewable && attrs.override_redirect == false && + ((attrs.width == w && attrs.height == h))) { win = children[j]; break; } @@ -1116,6 +1137,9 @@ void set_struts(alignment align) { if (strut != None) { long sizes[STRUT_COUNT] = {0}; + int display_width = workarea[2] - workarea[0]; + int display_height = workarea[3] - workarea[1]; + switch (horizontal_alignment(align)) { case axis_align::START: sizes[*x11_strut::LEFT] = diff --git a/src/x11.h b/src/x11.h index 7f983ae51..160fd21f5 100644 --- a/src/x11.h +++ b/src/x11.h @@ -98,6 +98,8 @@ struct conky_x11_window { extern struct conky_x11_window window; +void update_x11_resource_db(bool first_run = false); +void update_x11_workarea(); void init_x11(); void destroy_window(void); void create_gc(void);