Cleanup build flags, global namespace and includes (#1841)
- Separated displays so they don't have to all be included in build even when the features are disabled. - Removed weird linker magic for display init and replaced it with straightforward (and faster) template functions that behave the same. - Replaced `disabled_display_output` classes with log messages. - Add explicit compiler errors when feature dependent headers get included where they shouldn't (wl, x11). - Switch BUILD_MOUSE_EVENTS dependency from OWN_WINDOW to BUILD_X11. - Other minor improvements to some existing code which shouldn't affect behavior. - Improve documentation. - Remove X11 from unrelated headers. - This reaches 0% unneeded X11 polution in the sources. - Reenabled parts of window_type which would work in Wayland. - Remove unneeded guards. - Display files are now no longer compiled if their features are disabled. Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -11,11 +11,17 @@ doc/*.html
|
||||
Makefile
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
cmake_install.cmake
|
||||
cmake_uninstall.cmake
|
||||
CPackConfig.cmake
|
||||
CPackSourceConfig.cmake
|
||||
|
||||
data/convertconf.h
|
||||
data/defconfig.h
|
||||
*.so
|
||||
*.a
|
||||
/config.h
|
||||
/build.h
|
||||
|
||||
# Compiler cache
|
||||
.cache
|
||||
|
3
3rdparty/toluapp/.gitignore
vendored
3
3rdparty/toluapp/.gitignore
vendored
@@ -1 +1,4 @@
|
||||
build/
|
||||
|
||||
# ignore generated Makefile; keep stub
|
||||
Makefile
|
||||
|
@@ -193,8 +193,8 @@ dependent_option(BUILD_XSHAPE "Enable Xshape support" true
|
||||
"BUILD_X11" false
|
||||
"Xshape support requires X11")
|
||||
dependent_option(BUILD_XINPUT "Build Xinput 2 support" true
|
||||
"BUILD_X11;BUILD_MOUSE_EVENTS" false
|
||||
"Xinput 2 support requires X11 and BUILD_MOUSE_EVENTS enabled")
|
||||
"BUILD_X11" false
|
||||
"Xinput 2 support requires X11")
|
||||
|
||||
# if we build with any GUI support
|
||||
if(BUILD_X11)
|
||||
@@ -206,8 +206,8 @@ if(BUILD_WAYLAND)
|
||||
endif(BUILD_WAYLAND)
|
||||
|
||||
dependent_option(BUILD_MOUSE_EVENTS "Enable mouse event support" true
|
||||
"BUILD_WAYLAND OR OWN_WINDOW" false
|
||||
"Mouse event support requires Wayland or OWN_WINDOW enabled")
|
||||
"BUILD_WAYLAND OR BUILD_X11" false
|
||||
"Mouse event support requires Wayland or X11 enabled")
|
||||
|
||||
# Lua library options
|
||||
dependent_option(BUILD_LUA_CAIRO "Build cairo bindings for Lua" false
|
||||
@@ -247,9 +247,11 @@ option(BUILD_IRC "Enable if you want IRC support" false)
|
||||
|
||||
option(BUILD_HTTP "Enable if you want HTTP support" false)
|
||||
|
||||
if(BUILD_HTTP)
|
||||
if(NOT BUILD_HTTP)
|
||||
set(HTTPPORT "10080" CACHE STRING "Port to use for out_to_http")
|
||||
endif(BUILD_HTTP)
|
||||
else(NOT BUILD_HTTP)
|
||||
set(HTTPPORT "10080")
|
||||
endif(NOT BUILD_HTTP)
|
||||
|
||||
option(BUILD_ICONV "Enable iconv support" false)
|
||||
|
||||
|
@@ -10,7 +10,10 @@
|
||||
--
|
||||
-- For more on Lua, see:
|
||||
-- https://www.lua.org/pil/contents.html
|
||||
--
|
||||
-- Conky Lua API: https://conky.cc/lua
|
||||
|
||||
-- Configuration settings: https://conky.cc/config_settings
|
||||
conky.config = {
|
||||
alignment = 'bottom_left',
|
||||
background = false,
|
||||
@@ -36,7 +39,8 @@ conky.config = {
|
||||
extra_newline = false,
|
||||
own_window = false,
|
||||
own_window_class = 'Conky',
|
||||
own_window_type = 'desktop',
|
||||
own_window_type = 'normal',
|
||||
own_window_hints = 'undecorated,sticky,below,skip_taskbar,skip_pager',
|
||||
stippled_borders = 0,
|
||||
update_interval = 3.0,
|
||||
uppercase = false,
|
||||
@@ -45,6 +49,7 @@ conky.config = {
|
||||
show_graph_range = false
|
||||
}
|
||||
|
||||
-- Variables: https://conky.cc/variables
|
||||
conky.text = [[
|
||||
$sysname $version on $machine
|
||||
$hr
|
||||
|
@@ -10,7 +10,10 @@
|
||||
--
|
||||
-- For more on Lua, see:
|
||||
-- https://www.lua.org/pil/contents.html
|
||||
--
|
||||
-- Conky Lua API: https://conky.cc/lua
|
||||
|
||||
-- Configuration settings: https://conky.cc/config_settings
|
||||
conky.config = {
|
||||
alignment = 'top_left',
|
||||
background = false,
|
||||
@@ -39,7 +42,8 @@ conky.config = {
|
||||
out_to_x = true,
|
||||
own_window = true,
|
||||
own_window_class = 'Conky',
|
||||
own_window_type = 'desktop',
|
||||
own_window_type = 'normal',
|
||||
own_window_hints = 'undecorated,sticky,below,skip_taskbar,skip_pager',
|
||||
show_graph_range = false,
|
||||
show_graph_scale = false,
|
||||
stippled_borders = 0,
|
||||
@@ -49,6 +53,7 @@ conky.config = {
|
||||
use_xft = true,
|
||||
}
|
||||
|
||||
-- Variables: https://conky.cc/variables
|
||||
conky.text = [[
|
||||
${color grey}Info:$color ${scroll 32 Conky $conky_version - $sysname $nodename $kernel $machine}
|
||||
$hr
|
||||
|
@@ -10,7 +10,10 @@
|
||||
--
|
||||
-- For more on Lua, see:
|
||||
-- https://www.lua.org/pil/contents.html
|
||||
--
|
||||
-- Conky Lua API: https://conky.cc/lua
|
||||
|
||||
-- Configuration settings: https://conky.cc/config_settings
|
||||
conky.config = {
|
||||
background = false,
|
||||
cpu_avg_samples = 2,
|
||||
@@ -22,6 +25,7 @@ conky.config = {
|
||||
use_spacer = 'none',
|
||||
};
|
||||
|
||||
-- Variables: https://conky.cc/variables
|
||||
conky.text =
|
||||
[[${scroll 16 $nodename - $sysname $kernel on $machine | }
|
||||
Uptime: $uptime
|
||||
|
@@ -27,10 +27,38 @@ desc: |-
|
||||
values:
|
||||
- name: alignment
|
||||
desc: |-
|
||||
Aligned position on screen, may be top_left, top_right,
|
||||
top_middle, bottom_left, bottom_right, bottom_middle, middle_left,
|
||||
middle_middle, middle_right, or none (also can be abbreviated as tl,
|
||||
tr, tm, bl, br, bm, ml, mm, mr). See also gap_x and gap_y.
|
||||
Aligned position on screen, may be `none` or one of:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><code>top_left</code> (<em>or</em> <code>tl</code>)</td>
|
||||
<td><code>top_middle</code> (<em>or</em> <code>tm</code>)</td>
|
||||
<td><code>top_right</code> (<em>or</em> <code>tr</code>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>middle_left</code> (<em>or</em> <code>ml</code>)</td>
|
||||
<td><code>middle_middle</code> (<em>or</em> <code>mm</code>)</td>
|
||||
<td><code>middle_right</code> (<em>or</em> <code>mr</code>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>bottom_left</code> (<em>or</em> <code>bl</code>)</td>
|
||||
<td><code>bottom_middle</code> (<em>or</em> <code>bm</code>)</td>
|
||||
<td><code>bottom_right</code> (<em>or</em> <code>br</code>)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
In case of `panel` and `dock` windows, it might make more sense to use one
|
||||
of the following aliases:
|
||||
|
||||
| Alias | Value |
|
||||
|:------:|:-------------:|
|
||||
| `top` | `top_middle` |
|
||||
| `left` | `middle_left` |
|
||||
|`right` |`middle_right` |
|
||||
|`bottom`|`bottom_middle`|
|
||||
|`center`|`middle_middle`|
|
||||
|
||||
See also `gap_x` and `gap_y` settings.
|
||||
- name: append_file
|
||||
desc: Append the file given as argument.
|
||||
- name: background
|
||||
@@ -437,7 +465,7 @@ values:
|
||||
default: false
|
||||
- name: own_window_type
|
||||
desc: |-
|
||||
If own_window is set, under X11 you can specify type of window conky
|
||||
If `own_window` is set, under X11 you can specify type of window conky
|
||||
displayed as:
|
||||
|
||||
- `normal` mode makes conky show as normal window. This mode can be
|
||||
@@ -464,6 +492,7 @@ values:
|
||||
panels/windows as those will cover conky.
|
||||
`own_window_hints` are ignored for `override` windows.
|
||||
|
||||
To make conky mount on root window, set `own_window` to `false`.
|
||||
default: normal
|
||||
args:
|
||||
- (normal|desktop|dock|panel|utility|override)
|
||||
|
@@ -119,14 +119,6 @@ set(conky_sources
|
||||
display-console.hh
|
||||
display-file.cc
|
||||
display-file.hh
|
||||
display-ncurses.cc
|
||||
display-ncurses.hh
|
||||
display-http.cc
|
||||
display-http.hh
|
||||
display-x11.cc
|
||||
display-x11.hh
|
||||
display-wayland.cc
|
||||
display-wayland.hh
|
||||
lua-config.cc
|
||||
lua-config.hh
|
||||
setting.cc
|
||||
@@ -236,8 +228,23 @@ if(BUILD_PORT_MONITORS)
|
||||
set(optional_sources ${optional_sources} ${port_monitors})
|
||||
endif(BUILD_PORT_MONITORS)
|
||||
|
||||
if(BUILD_HTTP)
|
||||
set(http
|
||||
display-http.cc
|
||||
display-http.hh
|
||||
)
|
||||
set(optional_sources ${optional_sources} ${http})
|
||||
endif(BUILD_HTTP)
|
||||
|
||||
if(BUILD_X11)
|
||||
set(x11 x11.cc x11.h)
|
||||
set(x11
|
||||
display-x11.cc
|
||||
display-x11.hh
|
||||
x11-settings.cc
|
||||
x11-settings.h
|
||||
x11.cc
|
||||
x11.h
|
||||
)
|
||||
set(optional_sources ${optional_sources} ${x11})
|
||||
endif(BUILD_X11)
|
||||
|
||||
@@ -245,14 +252,22 @@ if(BUILD_GUI)
|
||||
set(gui fonts.cc fonts.h gui.cc gui.h)
|
||||
set(optional_sources ${optional_sources} ${gui})
|
||||
|
||||
if(BUILD_MOUSE_EVENTS)
|
||||
if(BUILD_MOUSE_EVENTS OR BUILD_XINPUT)
|
||||
set(mouse_events mouse-events.cc mouse-events.h)
|
||||
set(optional_sources ${optional_sources} ${mouse_events})
|
||||
endif(BUILD_MOUSE_EVENTS)
|
||||
endif(BUILD_MOUSE_EVENTS OR BUILD_XINPUT)
|
||||
endif(BUILD_GUI)
|
||||
|
||||
|
||||
if(BUILD_WAYLAND)
|
||||
set(wl_srcs wl.cc wl.h xdg-shell-protocol.c wlr-layer-shell-protocol.c)
|
||||
set(wl_srcs
|
||||
wl.cc
|
||||
wl.h
|
||||
display-wayland.cc
|
||||
display-wayland.hh
|
||||
xdg-shell-protocol.c
|
||||
wlr-layer-shell-protocol.c
|
||||
)
|
||||
set(optional_sources ${optional_sources} ${wl_srcs})
|
||||
|
||||
# generate protocol implementations
|
||||
@@ -324,7 +339,12 @@ if(BUILD_ICONV)
|
||||
endif(BUILD_ICONV)
|
||||
|
||||
if(BUILD_NCURSES)
|
||||
set(ncurses_srcs nc.cc nc.h)
|
||||
set(ncurses_srcs
|
||||
nc.cc
|
||||
nc.h
|
||||
display-ncurses.cc
|
||||
display-ncurses.hh
|
||||
)
|
||||
set(optional_sources ${optional_sources} ${ncurses_srcs})
|
||||
endif(BUILD_NCURSES)
|
||||
|
||||
|
144
src/colours.cc
144
src/colours.cc
@@ -26,25 +26,21 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include "conky.h"
|
||||
#include "gui.h"
|
||||
|
||||
#include "colours.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "x11-color.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
#ifdef BUILD_X11
|
||||
std::unordered_map<Colour, unsigned long, Colour::Hash> Colour::x11_pixels;
|
||||
#include <X11/Xlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
static int hex_nibble_value(char c) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
return c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
return c - 'a' + 10;
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
// sourced from X11, doesn't actually need X11
|
||||
#include "x11-color.h"
|
||||
|
||||
Colour Colour::from_argb32(uint32_t argb) {
|
||||
Colour out;
|
||||
@@ -55,29 +51,91 @@ Colour Colour::from_argb32(uint32_t argb) {
|
||||
return out;
|
||||
}
|
||||
|
||||
Colour error_colour{0xff, 0x00, 0x00, 0xff};
|
||||
#ifdef BUILD_X11
|
||||
unsigned long Colour::to_x11_color(Display *display, int screen,
|
||||
bool transparency, bool premultiply) {
|
||||
static std::unordered_map<Colour, unsigned long, Colour::Hash> x11_pixels;
|
||||
|
||||
Colour parse_color(const char *name) {
|
||||
unsigned short r, g, b;
|
||||
size_t len = strlen(name);
|
||||
// Parse X11 color names.
|
||||
if (OsLookupColor(-1, name, len, &r, &g, &b)) {
|
||||
Colour out = {(uint8_t)r, (uint8_t)g, (uint8_t)b, 0xff};
|
||||
return out;
|
||||
if (display == nullptr) {
|
||||
/* cannot work if display is not open */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Remove a leading '#' if present.
|
||||
unsigned long pixel;
|
||||
|
||||
/* Either get a cached X11 pixel or allocate one */
|
||||
if (auto pixel_iter = x11_pixels.find(*this);
|
||||
pixel_iter != x11_pixels.end()) {
|
||||
pixel = pixel_iter->second;
|
||||
} else {
|
||||
XColor xcolor{};
|
||||
xcolor.red = this->red * 257;
|
||||
xcolor.green = this->green * 257;
|
||||
xcolor.blue = this->blue * 257;
|
||||
if (XAllocColor(display, DefaultColormap(display, screen), &xcolor) == 0) {
|
||||
// NORM_ERR("can't allocate X color");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save pixel value in the cache to avoid reallocating it */
|
||||
x11_pixels[*this] = xcolor.pixel;
|
||||
pixel = static_cast<unsigned long>(xcolor.pixel);
|
||||
}
|
||||
|
||||
pixel &= 0xffffff;
|
||||
#ifdef BUILD_ARGB
|
||||
if (transparency) {
|
||||
if (premultiply)
|
||||
pixel = (red * alpha / 255) << 16 | (green * alpha / 255) << 8 |
|
||||
(blue * alpha / 255);
|
||||
pixel |= ((unsigned long)alpha << 24);
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
return pixel;
|
||||
}
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
std::optional<Colour> parse_color_name(const std::string &name) {
|
||||
unsigned short r, g, b;
|
||||
size_t len = name.length();
|
||||
// Parse X11 color names.
|
||||
if (OsLookupColor(name.c_str(), len, &r, &g, &b)) {
|
||||
return Colour{(uint8_t)r, (uint8_t)g, (uint8_t)b, 0xff};
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Colour> parse_hex_color(const std::string &color) {
|
||||
const char *name = color.c_str();
|
||||
size_t len = color.length();
|
||||
// Skip a leading '#' if present.
|
||||
if (name[0] == '#') {
|
||||
name++;
|
||||
len--;
|
||||
}
|
||||
|
||||
unsigned char argb[4] = {0xff, 0, 0, 0};
|
||||
static auto hex_nibble_value = [](char c) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
return c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
return c - 'a' + 10;
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
const auto none = [&]() {
|
||||
NORM_ERR("can't parse hex color '%s' (%d)", name, len);
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
uint8_t argb[4] = {0xff, 0, 0, 0};
|
||||
if (len == 3 || len == 4) {
|
||||
bool skip_alpha = (len == 3);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
int nib = hex_nibble_value(name[i]);
|
||||
if (nib < 0) { goto err; }
|
||||
if (nib < 0) { return none(); }
|
||||
// Duplicate the nibble, so "#abc" -> 0xaa, 0xbb, 0xcc
|
||||
int val = (nib << 4) + nib;
|
||||
|
||||
@@ -88,27 +146,35 @@ Colour parse_color(const char *name) {
|
||||
for (size_t i = 0; i + 1 < len; i += 2) {
|
||||
int nib1 = hex_nibble_value(name[i]);
|
||||
int nib2 = hex_nibble_value(name[i + 1]);
|
||||
if (nib1 < 0 || nib2 < 0) { goto err; }
|
||||
if (nib1 < 0 || nib2 < 0) { return none(); }
|
||||
int val = (nib1 << 4) + nib2;
|
||||
|
||||
argb[skip_alpha + i / 2] = val;
|
||||
}
|
||||
} else {
|
||||
goto err;
|
||||
return none();
|
||||
}
|
||||
|
||||
Colour out;
|
||||
out.alpha = argb[0];
|
||||
out.red = argb[1];
|
||||
out.green = argb[2];
|
||||
out.blue = argb[3];
|
||||
return out;
|
||||
|
||||
err:
|
||||
NORM_ERR("can't parse X color '%s' (%d)", name, len);
|
||||
return error_colour;
|
||||
return Colour(argb[1], argb[2], argb[3], argb[0]);
|
||||
}
|
||||
|
||||
Colour parse_color(const std::string &colour) {
|
||||
return parse_color(colour.c_str());
|
||||
Colour parse_color(const std::string &color) {
|
||||
std::optional<Colour> result;
|
||||
|
||||
#define TRY_PARSER(name) \
|
||||
std::optional<Colour> value_##name = name(color); \
|
||||
if (value_##name.has_value()) { return value_##name.value(); }
|
||||
|
||||
std::optional<Colour> value_parse_color_name = parse_color_name(color);
|
||||
if (value_parse_color_name.has_value()) {
|
||||
return value_parse_color_name.value();
|
||||
}
|
||||
std::optional<Colour> value_parse_hex_color = parse_hex_color(color);
|
||||
if (value_parse_hex_color.has_value()) {
|
||||
return value_parse_hex_color.value();
|
||||
}
|
||||
|
||||
#undef TRY_PARSER
|
||||
|
||||
return ERROR_COLOUR;
|
||||
}
|
||||
|
@@ -26,31 +26,50 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <config.h>
|
||||
#ifndef _COLOURS_H_
|
||||
#define _COLOURS_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
#include <X11/Xlib.h>
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
struct Colour {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t alpha;
|
||||
uint8_t alpha = 0xff;
|
||||
|
||||
public:
|
||||
Colour() = default;
|
||||
Colour(uint8_t r, uint8_t g, uint8_t b, uint8_t a = UINT8_MAX)
|
||||
: red(r), green(g), blue(b), alpha(a) {}
|
||||
Colour(const Colour &) = default;
|
||||
Colour(Colour &&) = default;
|
||||
|
||||
void operator=(const Colour &c) {
|
||||
red = c.red;
|
||||
green = c.green;
|
||||
blue = c.blue;
|
||||
alpha = c.alpha;
|
||||
}
|
||||
|
||||
// Compare two instances.
|
||||
bool operator==(const Colour &c) const {
|
||||
return c.red == red && c.green == green && c.blue == blue &&
|
||||
c.alpha == alpha;
|
||||
}
|
||||
|
||||
uint8_t *data() { return reinterpret_cast<uint8_t *>(this); }
|
||||
|
||||
// Express the color as a 32-bit ARGB integer (alpha in MSB).
|
||||
uint32_t to_argb32(void) const {
|
||||
uint32_t out;
|
||||
@@ -61,58 +80,20 @@ struct Colour {
|
||||
// Construct from a 32-bit ARGB integer (alpha in MSB).
|
||||
static Colour from_argb32(uint32_t argb);
|
||||
|
||||
#ifdef BUILD_X11
|
||||
class Hash {
|
||||
public:
|
||||
size_t operator()(const Colour &c) const { return c.to_argb32(); }
|
||||
};
|
||||
|
||||
static std::unordered_map<Colour, unsigned long, Hash> x11_pixels;
|
||||
#ifdef BUILD_X11
|
||||
unsigned long to_x11_color(Display *display, int screen,
|
||||
bool premultiply = false) {
|
||||
if (display == nullptr) {
|
||||
/* cannot work if display is not open */
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long pixel;
|
||||
|
||||
/* Either get a cached X11 pixel or allocate one */
|
||||
if (auto pixel_iter = x11_pixels.find(*this);
|
||||
pixel_iter != x11_pixels.end()) {
|
||||
pixel = pixel_iter->second;
|
||||
} else {
|
||||
XColor xcolor{};
|
||||
xcolor.red = red * 257;
|
||||
xcolor.green = green * 257;
|
||||
xcolor.blue = blue * 257;
|
||||
if (XAllocColor(display, DefaultColormap(display, screen), &xcolor) ==
|
||||
0) {
|
||||
// NORM_ERR("can't allocate X color");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save pixel value in the cache to avoid reallocating it */
|
||||
x11_pixels[*this] = xcolor.pixel;
|
||||
pixel = static_cast<unsigned long>(xcolor.pixel);
|
||||
}
|
||||
|
||||
pixel &= 0xffffff;
|
||||
#ifdef BUILD_ARGB
|
||||
if (have_argb_visual) {
|
||||
if (premultiply)
|
||||
pixel = (red * alpha / 255) << 16 | (green * alpha / 255) << 8 |
|
||||
(blue * alpha / 255);
|
||||
pixel |= ((unsigned long)alpha << 24);
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
return pixel;
|
||||
}
|
||||
bool transparency = false,
|
||||
bool premultiply = false);
|
||||
#endif /* BUILD_X11 */
|
||||
};
|
||||
|
||||
extern Colour error_colour;
|
||||
const Colour ERROR_COLOUR = Colour{UINT8_MAX, 0, 0, UINT8_MAX};
|
||||
|
||||
Colour parse_color(const std::string &colour);
|
||||
// XXX: when everyone uses C++ strings, remove this C version
|
||||
Colour parse_color(const char *);
|
||||
Colour parse_color(const std::string &color);
|
||||
|
||||
#endif /* _COLOURS_H_ */
|
||||
|
@@ -22,8 +22,9 @@
|
||||
*/
|
||||
|
||||
#include "conky-imlib2.h"
|
||||
#include "config.h"
|
||||
#include "conky.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "display-output.hh"
|
||||
#include "logging.h"
|
||||
#include "text_object.h"
|
||||
|
||||
@@ -47,22 +48,24 @@ struct image_list_s {
|
||||
};
|
||||
|
||||
struct image_list_s *image_list_start, *image_list_end;
|
||||
std::array<std::array<int, 2>, 100> saved_coordinates;
|
||||
|
||||
/* areas to update */
|
||||
Imlib_Updates updates, current_update;
|
||||
/* our virtual framebuffer image we draw into */
|
||||
Imlib_Image buffer, image;
|
||||
|
||||
namespace {
|
||||
Imlib_Context context;
|
||||
|
||||
conky::range_config_setting<unsigned int> imlib_cache_flush_interval(
|
||||
"imlib_cache_flush_interval", 0, std::numeric_limits<unsigned int>::max(),
|
||||
0, true);
|
||||
|
||||
unsigned int cimlib_cache_flush_last = 0;
|
||||
conky::simple_config_setting<bool> imlib_draw_blended("draw_blended", true,
|
||||
true);
|
||||
|
||||
conky::simple_config_setting<bool> draw_blended("draw_blended", true, true);
|
||||
namespace {
|
||||
Imlib_Context context;
|
||||
|
||||
unsigned int cimlib_cache_flush_last = 0;
|
||||
} // namespace
|
||||
|
||||
void imlib_cache_size_setting::lua_setter(lua::state &l, bool init) {
|
||||
@@ -162,8 +165,9 @@ void cimlib_add_image(const char *args) {
|
||||
tmp += 3;
|
||||
int i;
|
||||
if (sscanf(tmp, "%d", &i) == 1) {
|
||||
cur->x = get_saved_coordinates_x(i);
|
||||
cur->y = get_saved_coordinates_y(i);
|
||||
const auto &coordinates = saved_coordinates.at(static_cast<size_t>(i));
|
||||
cur->x = coordinates[0];
|
||||
cur->y = coordinates[1];
|
||||
}
|
||||
}
|
||||
if (cur->flush_interval < 0) {
|
||||
@@ -237,7 +241,8 @@ static void cimlib_draw_all(int *clip_x, int *clip_y, int *clip_x2,
|
||||
}
|
||||
}
|
||||
|
||||
void cimlib_render(int x, int y, int width, int height) {
|
||||
void cimlib_render(int x, int y, int width, int height, uint32_t flush_interval,
|
||||
bool draw_blended) {
|
||||
int clip_x = INT_MAX, clip_y = INT_MAX;
|
||||
int clip_x2 = 0, clip_y2 = 0;
|
||||
time_t now;
|
||||
@@ -248,8 +253,8 @@ void cimlib_render(int x, int y, int width, int height) {
|
||||
|
||||
/* cheque if it's time to flush our cache */
|
||||
now = time(nullptr);
|
||||
if ((imlib_cache_flush_interval.get(*state) != 0u) &&
|
||||
now - imlib_cache_flush_interval.get(*state) > cimlib_cache_flush_last) {
|
||||
if ((flush_interval != 0u) &&
|
||||
now - flush_interval > cimlib_cache_flush_last) {
|
||||
int size = imlib_get_cache_size();
|
||||
imlib_set_cache_size(0);
|
||||
imlib_set_cache_size(size);
|
||||
@@ -265,7 +270,7 @@ void cimlib_render(int x, int y, int width, int height) {
|
||||
imlib_image_clear();
|
||||
|
||||
/* check if we should blend when rendering */
|
||||
if (draw_blended.get(*state)) {
|
||||
if (draw_blended) {
|
||||
/* we can blend stuff now */
|
||||
imlib_context_set_blend(1);
|
||||
} else {
|
||||
@@ -295,3 +300,5 @@ void cimlib_render(int x, int y, int width, int height) {
|
||||
void print_image_callback(struct text_object *obj, char *, unsigned int) {
|
||||
cimlib_add_image(obj->data.s);
|
||||
}
|
||||
|
||||
imlib_cache_size_setting imlib_cache_size;
|
||||
|
@@ -24,17 +24,24 @@
|
||||
#ifndef _CONKY_IMBLI2_H_
|
||||
#define _CONKY_IMBLI2_H_
|
||||
|
||||
#include "conky.h"
|
||||
#include "setting.hh"
|
||||
#include "text_object.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
#include <X11/Xlib.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
using saved_coordinates_t = std::array<std::array<int, 2>, 100>;
|
||||
extern saved_coordinates_t saved_coordinates;
|
||||
|
||||
void cimlib_add_image(const char *args);
|
||||
void cimlib_set_cache_size(long size);
|
||||
void cimlib_set_cache_flush_interval(long interval);
|
||||
void cimlib_render(int x, int y, int width, int height);
|
||||
void cimlib_render(int x, int y, int width, int height, uint32_t flush_interval,
|
||||
bool draw_blended);
|
||||
void cimlib_cleanup(void);
|
||||
|
||||
void print_image_callback(struct text_object *, char *, unsigned int);
|
||||
@@ -53,4 +60,7 @@ class imlib_cache_size_setting
|
||||
4096 * 1024, true) {}
|
||||
};
|
||||
|
||||
extern conky::range_config_setting<unsigned int> imlib_cache_flush_interval;
|
||||
extern conky::simple_config_setting<bool> imlib_draw_blended;
|
||||
|
||||
#endif /* _CONKY_IMBLI2_H_ */
|
||||
|
206
src/conky.cc
206
src/conky.cc
@@ -28,6 +28,9 @@
|
||||
*/
|
||||
|
||||
#include "conky.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
@@ -40,24 +43,37 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "text_object.h"
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif /* HAVE_DIRENT_H */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_SYS_INOTIFY_H
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#include <sys/inotify.h>
|
||||
#pragma clang diagnostic pop
|
||||
#endif /* HAVE_SYS_INOTIFY_H */
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif /* HAVE_DIRENT_H */
|
||||
|
||||
#include "common.h"
|
||||
#include "text_object.h"
|
||||
|
||||
#ifdef BUILD_WAYLAND
|
||||
#include "wl.h"
|
||||
#endif /* BUILD_WAYLAND */
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
#include <X11/Xutil.h>
|
||||
@@ -69,21 +85,18 @@
|
||||
#include "conky-imlib2.h"
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#ifdef BUILD_NCURSES
|
||||
#include <ncurses.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#if defined BUILD_RSS
|
||||
#include <libxml/parser.h>
|
||||
#endif
|
||||
#endif /* BUILD_NCURSES */
|
||||
|
||||
#ifdef BUILD_CURL
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
#endif /* BUILD_CURL */
|
||||
|
||||
#ifdef BUILD_RSS
|
||||
#include <libxml/parser.h>
|
||||
#endif /* BUILD_RSS */
|
||||
|
||||
/* local headers */
|
||||
#include "colours.h"
|
||||
@@ -97,7 +110,7 @@
|
||||
#include "fs.h"
|
||||
#ifdef BUILD_ICONV
|
||||
#include "iconv_tools.h"
|
||||
#endif
|
||||
#endif /* BUILD_ICONV */
|
||||
#include "llua.h"
|
||||
#include "logging.h"
|
||||
#include "mail.h"
|
||||
@@ -108,12 +121,13 @@
|
||||
#include "template.h"
|
||||
#include "timeinfo.h"
|
||||
#include "top.h"
|
||||
|
||||
#ifdef BUILD_MYSQL
|
||||
#include "mysql.h"
|
||||
#endif /* BUILD_MYSQL */
|
||||
#ifdef BUILD_NVIDIA
|
||||
#include "nvidia.h"
|
||||
#endif
|
||||
#endif /* BUILD_NVIDIA */
|
||||
#ifdef BUILD_CURL
|
||||
#include "ccurl_thread.h"
|
||||
#endif /* BUILD_CURL */
|
||||
@@ -394,18 +408,6 @@ int calc_text_width(const char *s) {
|
||||
return slen;
|
||||
}
|
||||
|
||||
int dpi_scale(int value) {
|
||||
#ifdef BUILD_GUI
|
||||
if (display_output()) {
|
||||
return display_output()->dpi_scale(value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
#else /* BUILD_GUI */
|
||||
return value;
|
||||
#endif /* BUILD_GUI */
|
||||
}
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
conky::gradient_factory *create_gradient_factory(int width, Colour first_colour,
|
||||
Colour last_colour) {
|
||||
@@ -766,7 +768,7 @@ void remove_first_char(char *s) { memmove(s, s + 1, strlen(s)); }
|
||||
|
||||
static int get_string_width_special(char *s, int special_index) {
|
||||
char *p, *final;
|
||||
special_t *current = specials;
|
||||
special_node *current = specials;
|
||||
int width = 0;
|
||||
long i;
|
||||
|
||||
@@ -789,22 +791,23 @@ static int get_string_width_special(char *s, int special_index) {
|
||||
/*for (i = 0; i < static_cast<long>(strlen(p)); i++) {
|
||||
*(p + i) = *(p + i + 1);
|
||||
}*/
|
||||
if (current->type == GRAPH || current->type == GAUGE ||
|
||||
current->type == BAR) {
|
||||
if (current->type == text_node_t::GRAPH ||
|
||||
current->type == text_node_t::GAUGE ||
|
||||
current->type == text_node_t::BAR) {
|
||||
width += current->width;
|
||||
}
|
||||
if (current->type == FONT) {
|
||||
if (current->type == text_node_t::FONT) {
|
||||
// put all following text until the next fontchange/stringend in
|
||||
// influenced_by_font but do not include specials
|
||||
char *influenced_by_font = strdup(p);
|
||||
special_t *current_after_font = current;
|
||||
special_node *current_after_font = current;
|
||||
// influenced_by_font gets special chars removed, so after this loop i
|
||||
// counts the number of letters (not special chars) influenced by font
|
||||
for (i = 0; influenced_by_font[i] != 0; i++) {
|
||||
if (influenced_by_font[i] == SPECIAL_CHAR) {
|
||||
// remove specials and stop at fontchange
|
||||
current_after_font = current_after_font->next;
|
||||
if (current_after_font->type == FONT) {
|
||||
if (current_after_font->type == text_node_t::FONT) {
|
||||
influenced_by_font[i] = 0;
|
||||
break;
|
||||
}
|
||||
@@ -867,50 +870,34 @@ void update_text_area() {
|
||||
|
||||
alignment align = text_alignment.get(*state);
|
||||
/* get text position on workarea */
|
||||
switch (align) {
|
||||
case TOP_LEFT:
|
||||
case TOP_RIGHT:
|
||||
case TOP_MIDDLE:
|
||||
switch (vertical_alignment(align)) {
|
||||
case axis_align::START:
|
||||
y = workarea[1] + dpi_scale(gap_y.get(*state));
|
||||
break;
|
||||
|
||||
case BOTTOM_LEFT:
|
||||
case BOTTOM_RIGHT:
|
||||
case BOTTOM_MIDDLE:
|
||||
case axis_align::END:
|
||||
default:
|
||||
y = workarea[3] - text_height - dpi_scale(gap_y.get(*state));
|
||||
break;
|
||||
|
||||
case MIDDLE_LEFT:
|
||||
case MIDDLE_RIGHT:
|
||||
case MIDDLE_MIDDLE:
|
||||
case axis_align::MIDDLE:
|
||||
y = workarea[1] + (workarea[3] - workarea[1]) / 2 - text_height / 2 -
|
||||
dpi_scale(gap_y.get(*state));
|
||||
break;
|
||||
}
|
||||
switch (align) {
|
||||
case TOP_LEFT:
|
||||
case BOTTOM_LEFT:
|
||||
case MIDDLE_LEFT:
|
||||
switch (horizontal_alignment(align)) {
|
||||
case axis_align::START:
|
||||
default:
|
||||
x = workarea[0] + dpi_scale(gap_x.get(*state));
|
||||
break;
|
||||
|
||||
case TOP_RIGHT:
|
||||
case BOTTOM_RIGHT:
|
||||
case MIDDLE_RIGHT:
|
||||
case axis_align::END:
|
||||
x = workarea[2] - text_width - dpi_scale(gap_x.get(*state));
|
||||
break;
|
||||
|
||||
case TOP_MIDDLE:
|
||||
case BOTTOM_MIDDLE:
|
||||
case MIDDLE_MIDDLE:
|
||||
case axis_align::MIDDLE:
|
||||
x = workarea[0] + (workarea[2] - workarea[0]) / 2 - text_width / 2 -
|
||||
dpi_scale(gap_x.get(*state));
|
||||
break;
|
||||
}
|
||||
#ifdef OWN_WINDOW
|
||||
if (align == NONE) { // Let the WM manage the window
|
||||
if (align == alignment::NONE) { // Let the WM manage the window
|
||||
x = window.x;
|
||||
y = window.y;
|
||||
|
||||
@@ -941,20 +928,14 @@ static int cur_x, cur_y; /* current x and y for drawing */
|
||||
#endif
|
||||
// draw_mode also without BUILD_GUI because we only need to print to stdout with
|
||||
// FG
|
||||
static int draw_mode; /* FG, BG or OUTLINE */
|
||||
static draw_mode_t draw_mode; /* FG, BG or OUTLINE */
|
||||
#ifdef BUILD_GUI
|
||||
/*static*/ Colour current_color;
|
||||
|
||||
static int saved_coordinates_x[100];
|
||||
static int saved_coordinates_y[100];
|
||||
|
||||
int get_saved_coordinates_x(int i) { return saved_coordinates_x[i]; }
|
||||
int get_saved_coordinates_y(int i) { return saved_coordinates_y[i]; }
|
||||
|
||||
static int text_size_updater(char *s, int special_index) {
|
||||
int w = 0;
|
||||
char *p;
|
||||
special_t *current = specials;
|
||||
special_node *current = specials;
|
||||
|
||||
for (int i = 0; i < special_index; i++) { current = current->next; }
|
||||
|
||||
@@ -969,26 +950,27 @@ static int text_size_updater(char *s, int special_index) {
|
||||
w += get_string_width(s);
|
||||
*p = SPECIAL_CHAR;
|
||||
|
||||
if (current->type == BAR || current->type == GAUGE ||
|
||||
current->type == GRAPH) {
|
||||
if (current->type == text_node_t::BAR ||
|
||||
current->type == text_node_t::GAUGE ||
|
||||
current->type == text_node_t::GRAPH) {
|
||||
w += current->width;
|
||||
if (current->height > last_font_height) {
|
||||
last_font_height = current->height;
|
||||
last_font_height += font_height();
|
||||
}
|
||||
} else if (current->type == OFFSET) {
|
||||
} else if (current->type == text_node_t::OFFSET) {
|
||||
if (current->arg > 0) { w += current->arg; }
|
||||
} else if (current->type == VOFFSET) {
|
||||
} else if (current->type == text_node_t::VOFFSET) {
|
||||
last_font_height += current->arg;
|
||||
} else if (current->type == GOTO) {
|
||||
} else if (current->type == text_node_t::GOTO) {
|
||||
if (current->arg > cur_x) { w = static_cast<int>(current->arg); }
|
||||
} else if (current->type == TAB) {
|
||||
} else if (current->type == text_node_t::TAB) {
|
||||
int start = current->arg;
|
||||
int step = current->width;
|
||||
|
||||
if ((step == 0) || step < 0) { step = 10; }
|
||||
w += step - (cur_x - text_start_x - start) % step;
|
||||
} else if (current->type == FONT) {
|
||||
} else if (current->type == text_node_t::FONT) {
|
||||
selected_font = current->font_added;
|
||||
if (font_height() > last_font_height) {
|
||||
last_font_height = font_height();
|
||||
@@ -1033,7 +1015,7 @@ static void draw_string(const char *s) {
|
||||
#ifdef BUILD_GUI
|
||||
width_of_s = get_string_width(s);
|
||||
#endif /* BUILD_GUI */
|
||||
if (draw_mode == FG) {
|
||||
if (draw_mode == draw_mode_t::FG) {
|
||||
for (auto output : display_outputs())
|
||||
if (!output->graphical()) output->draw_string(s, 0);
|
||||
}
|
||||
@@ -1163,11 +1145,11 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
s = p + 1;
|
||||
}
|
||||
/* draw special */
|
||||
special_t *current = specials;
|
||||
special_node *current = specials;
|
||||
for (int i = 0; i < special_index; i++) { current = current->next; }
|
||||
switch (current->type) {
|
||||
#ifdef BUILD_GUI
|
||||
case HORIZONTAL_LINE:
|
||||
case text_node_t::HORIZONTAL_LINE:
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
int h = current->height;
|
||||
int mid = font_ascent() / 2;
|
||||
@@ -1183,7 +1165,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
}
|
||||
break;
|
||||
|
||||
case STIPPLED_HR:
|
||||
case text_node_t::STIPPLED_HR:
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
int h = current->height;
|
||||
char tmp_s = current->arg;
|
||||
@@ -1201,7 +1183,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
}
|
||||
break;
|
||||
|
||||
case BAR:
|
||||
case text_node_t::BAR:
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
int h, by;
|
||||
double bar_usage, scale;
|
||||
@@ -1229,7 +1211,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
}
|
||||
break;
|
||||
|
||||
case GAUGE: /* new GAUGE */
|
||||
case text_node_t::GAUGE: /* new GAUGE */
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
int h, by = 0;
|
||||
Colour last_colour = current_color;
|
||||
@@ -1279,7 +1261,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
}
|
||||
break;
|
||||
|
||||
case GRAPH:
|
||||
case text_node_t::GRAPH:
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
int h, by, i = 0, j = 0;
|
||||
int colour_idx = 0;
|
||||
@@ -1415,7 +1397,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
}
|
||||
break;
|
||||
|
||||
case FONT:
|
||||
case text_node_t::FONT:
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
int old = font_ascent();
|
||||
|
||||
@@ -1431,41 +1413,42 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
}
|
||||
break;
|
||||
#endif /* BUILD_GUI */
|
||||
case FG:
|
||||
if (draw_mode == FG) {
|
||||
case text_node_t::FG:
|
||||
if (draw_mode == draw_mode_t::FG) {
|
||||
set_foreground_color(Colour::from_argb32(current->arg));
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
case BG:
|
||||
if (draw_mode == BG) {
|
||||
case text_node_t::BG:
|
||||
if (draw_mode == draw_mode_t::BG) {
|
||||
set_foreground_color(Colour::from_argb32(current->arg));
|
||||
}
|
||||
break;
|
||||
|
||||
case OUTLINE:
|
||||
if (draw_mode == OUTLINE) {
|
||||
case text_node_t::OUTLINE:
|
||||
if (draw_mode == draw_mode_t::OUTLINE) {
|
||||
set_foreground_color(Colour::from_argb32(current->arg));
|
||||
}
|
||||
break;
|
||||
|
||||
case OFFSET:
|
||||
case text_node_t::OFFSET:
|
||||
w += current->arg;
|
||||
break;
|
||||
|
||||
case VOFFSET:
|
||||
case text_node_t::VOFFSET:
|
||||
cur_y += current->arg;
|
||||
break;
|
||||
|
||||
case SAVE_COORDINATES:
|
||||
saved_coordinates_x[static_cast<int>(current->arg)] =
|
||||
cur_x - text_start_x;
|
||||
saved_coordinates_y[static_cast<int>(current->arg)] =
|
||||
cur_y - text_start_y - last_font_height;
|
||||
case text_node_t::SAVE_COORDINATES:
|
||||
#ifdef BUILD_IMLIB2
|
||||
saved_coordinates[static_cast<int>(current->arg)] =
|
||||
std::array<int, 2>{cur_x - text_start_x,
|
||||
cur_y - text_start_y - last_font_height};
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
break;
|
||||
|
||||
case TAB: {
|
||||
case text_node_t::TAB: {
|
||||
int start = current->arg;
|
||||
int step = current->width;
|
||||
|
||||
@@ -1474,7 +1457,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ALIGNR: {
|
||||
case text_node_t::ALIGNR: {
|
||||
/* TODO: add back in "+ window.border_inner_margin" to the end of
|
||||
* this line? */
|
||||
int pos_x = text_start_x + text_width -
|
||||
@@ -1491,7 +1474,7 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ALIGNC: {
|
||||
case text_node_t::ALIGNC: {
|
||||
int pos_x = (text_width) / 2 -
|
||||
get_string_width_special(s, special_index) / 2 -
|
||||
(cur_x - text_start_x);
|
||||
@@ -1507,17 +1490,20 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) {
|
||||
break;
|
||||
}
|
||||
#endif /* BUILD_GUI */
|
||||
case GOTO:
|
||||
case text_node_t::GOTO:
|
||||
if (current->arg >= 0) {
|
||||
#ifdef BUILD_GUI
|
||||
cur_x = static_cast<int>(current->arg);
|
||||
// make sure shades are 1 pixel to the right of the text
|
||||
if (draw_mode == BG) { cur_x++; }
|
||||
if (draw_mode == draw_mode_t::BG) { cur_x++; }
|
||||
#endif /* BUILD_GUI */
|
||||
cur_x = static_cast<int>(current->arg);
|
||||
for (auto output : display_outputs()) output->gotox(cur_x);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// do nothing; not a special node or support not enabled
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
@@ -1599,7 +1585,9 @@ void draw_stuff() {
|
||||
|
||||
#ifdef BUILD_IMLIB2
|
||||
text_offset_x = text_offset_y = 0;
|
||||
cimlib_render(text_start_x, text_start_y, window.width, window.height);
|
||||
cimlib_render(text_start_x, text_start_y, window.width, window.height,
|
||||
imlib_cache_flush_interval.get(*state),
|
||||
imlib_draw_blended.get(*state));
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
|
||||
for (auto output : display_outputs()) {
|
||||
@@ -1611,7 +1599,7 @@ void draw_stuff() {
|
||||
if (draw_shades.get(*state) && !draw_outline.get(*state)) {
|
||||
text_offset_x = text_offset_y = 1;
|
||||
set_foreground_color(default_shade_color.get(*state));
|
||||
draw_mode = BG;
|
||||
draw_mode = draw_mode_t::BG;
|
||||
draw_text();
|
||||
text_offset_x = text_offset_y = 0;
|
||||
}
|
||||
@@ -1623,7 +1611,7 @@ void draw_stuff() {
|
||||
for (text_offset_y = -1; text_offset_y < 2; text_offset_y++) {
|
||||
if (text_offset_x == 0 && text_offset_y == 0) { continue; }
|
||||
set_foreground_color(default_outline_color.get(*state));
|
||||
draw_mode = OUTLINE;
|
||||
draw_mode = draw_mode_t::OUTLINE;
|
||||
draw_text();
|
||||
}
|
||||
}
|
||||
@@ -1637,7 +1625,7 @@ void draw_stuff() {
|
||||
|
||||
#endif /* BUILD_GUI */
|
||||
// always draw text
|
||||
draw_mode = FG;
|
||||
draw_mode = draw_mode_t::FG;
|
||||
draw_text();
|
||||
#ifdef BUILD_GUI
|
||||
|
||||
@@ -1874,10 +1862,10 @@ static void reload_config() {
|
||||
initialisation(argc_copy, argv_copy);
|
||||
}
|
||||
|
||||
void free_specials(special_t *¤t) {
|
||||
void free_specials(special_node *¤t) {
|
||||
if (current != nullptr) {
|
||||
free_specials(current->next);
|
||||
if (current->type == GRAPH) { free(current->graph); }
|
||||
if (current->type == text_node_t::GRAPH) { free(current->graph); }
|
||||
delete current;
|
||||
current = nullptr;
|
||||
}
|
||||
|
@@ -32,11 +32,14 @@
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <config.h> /* defines */
|
||||
#include <sys/utsname.h> /* struct uname_s */
|
||||
#include <csignal>
|
||||
#include <memory>
|
||||
|
||||
#include "colours.h"
|
||||
#include "common.h" /* at least for struct dns_data */
|
||||
#include "luamm.hh"
|
||||
@@ -311,11 +314,6 @@ void set_updatereset(int);
|
||||
int get_updatereset(void);
|
||||
int get_total_updates(void);
|
||||
|
||||
int dpi_scale(int value);
|
||||
|
||||
int get_saved_coordinates_x(int);
|
||||
int get_saved_coordinates_y(int);
|
||||
|
||||
/* defined in conky.c */
|
||||
int spaced_print(char *, int, const char *, int, ...)
|
||||
__attribute__((format(printf, 3, 5)));
|
||||
|
25
src/core.cc
25
src/core.cc
@@ -27,9 +27,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* local headers */
|
||||
#include "core.h"
|
||||
#include "algebra.h"
|
||||
#include "core.h"
|
||||
|
||||
#include "bsdapm.h"
|
||||
#include "build.h"
|
||||
#include "colour-settings.h"
|
||||
@@ -40,11 +43,11 @@
|
||||
#include "exec.h"
|
||||
#include "i8k.h"
|
||||
#include "misc.h"
|
||||
#include "proc.h"
|
||||
#include "text_object.h"
|
||||
#ifdef BUILD_IMLIB2
|
||||
#include "conky-imlib2.h"
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#include "proc.h"
|
||||
#ifdef BUILD_MYSQL
|
||||
#include "mysql.h"
|
||||
#endif /* BUILD_MYSQL */
|
||||
@@ -1893,9 +1896,10 @@ struct text_object *construct_text_object(char *s, const char *arg, long line,
|
||||
obj->callbacks.print = &print_combine;
|
||||
obj->callbacks.free = &free_combine;
|
||||
#ifdef BUILD_NVIDIA
|
||||
END OBJ_ARG(
|
||||
nvidia, 0,
|
||||
"nvidia needs an argument") if (set_nvidia_query(obj, arg, NONSPECIAL)) {
|
||||
END OBJ_ARG(nvidia, 0, "nvidia needs an argument") if (set_nvidia_query(
|
||||
obj, arg,
|
||||
text_node_t::
|
||||
NONSPECIAL)) {
|
||||
CRIT_ERR_FREE(obj, free_at_crash,
|
||||
"nvidia: invalid argument"
|
||||
" specified: '%s'",
|
||||
@@ -1905,7 +1909,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line,
|
||||
obj->callbacks.free = &free_nvidia;
|
||||
END OBJ_ARG(
|
||||
nvidiabar, 0,
|
||||
"nvidiabar needs an argument") if (set_nvidia_query(obj, arg, BAR)) {
|
||||
"nvidiabar needs an argument") if (set_nvidia_query(obj, arg,
|
||||
text_node_t::BAR)) {
|
||||
CRIT_ERR_FREE(obj, free_at_crash,
|
||||
"nvidiabar: invalid argument"
|
||||
" specified: '%s'",
|
||||
@@ -1915,7 +1920,9 @@ struct text_object *construct_text_object(char *s, const char *arg, long line,
|
||||
obj->callbacks.free = &free_nvidia;
|
||||
END OBJ_ARG(
|
||||
nvidiagraph, 0,
|
||||
"nvidiagraph needs an argument") if (set_nvidia_query(obj, arg, GRAPH)) {
|
||||
"nvidiagraph needs an argument") if (set_nvidia_query(obj, arg,
|
||||
text_node_t::
|
||||
GRAPH)) {
|
||||
CRIT_ERR_FREE(obj, free_at_crash,
|
||||
"nvidiagraph: invalid argument"
|
||||
" specified: '%s'",
|
||||
@@ -1925,7 +1932,9 @@ struct text_object *construct_text_object(char *s, const char *arg, long line,
|
||||
obj->callbacks.free = &free_nvidia;
|
||||
END OBJ_ARG(
|
||||
nvidiagauge, 0,
|
||||
"nvidiagauge needs an argument") if (set_nvidia_query(obj, arg, GAUGE)) {
|
||||
"nvidiagauge needs an argument") if (set_nvidia_query(obj, arg,
|
||||
text_node_t::
|
||||
GAUGE)) {
|
||||
CRIT_ERR_FREE(obj, free_at_crash,
|
||||
"nvidiagauge: invalid argument"
|
||||
" specified: '%s'",
|
||||
|
@@ -43,9 +43,11 @@ namespace {
|
||||
conky::display_output_console console_output("console");
|
||||
|
||||
} // namespace
|
||||
void init_console_output() {}
|
||||
|
||||
namespace priv {} // namespace priv
|
||||
template <>
|
||||
void register_output<output_t::CONSOLE>(display_outputs_t &outputs) {
|
||||
outputs.push_back(&console_output);
|
||||
}
|
||||
|
||||
display_output_console::display_output_console(const std::string &name_)
|
||||
: display_output_base(name_) {
|
||||
|
@@ -49,9 +49,10 @@ namespace {
|
||||
conky::display_output_file file_output("file");
|
||||
|
||||
} // namespace
|
||||
extern void init_file_output() {}
|
||||
|
||||
namespace priv {} // namespace priv
|
||||
template <>
|
||||
void register_output<output_t::FILE>(display_outputs_t &outputs) {
|
||||
outputs.push_back(&file_output);
|
||||
}
|
||||
|
||||
display_output_file::display_output_file(const std::string &name_)
|
||||
: display_output_base(name_) {
|
||||
|
@@ -33,26 +33,20 @@
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef BUILD_HTTP
|
||||
#include <microhttpd.h>
|
||||
#endif /* BUILD_HTTP */
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
|
||||
#ifdef BUILD_HTTP
|
||||
conky::display_output_http http_output;
|
||||
#else
|
||||
conky::disabled_display_output http_output_disabled("http", "BUILD_HTTP");
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
extern void init_http_output() {}
|
||||
template <>
|
||||
void register_output<output_t::HTTP>(display_outputs_t &outputs) {
|
||||
outputs.push_back(&http_output);
|
||||
}
|
||||
|
||||
// TODO: cleanup namespace
|
||||
// namespace priv {
|
||||
|
||||
#ifdef BUILD_HTTP
|
||||
#ifdef MHD_YES
|
||||
/* older API */
|
||||
#define MHD_Result int
|
||||
@@ -130,12 +124,8 @@ std::string string_replace_all(std::string original, const std::string &oldpart,
|
||||
return original;
|
||||
}
|
||||
|
||||
#endif /* BUILD_HTTP */
|
||||
|
||||
//} // namespace priv
|
||||
|
||||
#ifdef BUILD_HTTP
|
||||
|
||||
display_output_http::display_output_http() : display_output_base("http") {
|
||||
priority = 0;
|
||||
httpd = NULL;
|
||||
@@ -192,6 +182,4 @@ void display_output_http::draw_string(const char *s, int) {
|
||||
webpage.append("<br />");
|
||||
}
|
||||
|
||||
#endif /* BUILD_HTTP */
|
||||
|
||||
} // namespace conky
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#ifndef DISPLAY_HTTP_HH
|
||||
#define DISPLAY_HTTP_HH
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
@@ -35,33 +35,24 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#ifdef BUILD_NCURSES
|
||||
#include <ncurses.h>
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_NCURSES
|
||||
#include <ncurses.h>
|
||||
|
||||
extern WINDOW* ncurses_window;
|
||||
#endif
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
|
||||
#ifdef BUILD_NCURSES
|
||||
conky::display_output_ncurses ncurses_output;
|
||||
#else
|
||||
conky::disabled_display_output ncurses_output_disabled("ncurses",
|
||||
"BUILD_NCURSES");
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
extern void init_ncurses_output() {}
|
||||
template <>
|
||||
void register_output<output_t::NCURSES>(display_outputs_t& outputs) {
|
||||
outputs.push_back(&ncurses_output);
|
||||
}
|
||||
|
||||
// namespace priv {
|
||||
|
||||
//} // namespace priv
|
||||
|
||||
#ifdef BUILD_NCURSES
|
||||
|
||||
#define COLORS_BUILTIN 8
|
||||
|
||||
Colour ncurses_colors[COLORS_BUILTIN + COLORS_CUSTOM] = {
|
||||
@@ -96,7 +87,7 @@ Colour from_ncurses(int nccolor) {
|
||||
if (nccolor >= 0 && nccolor < COLORS_BUILTIN + COLORS_CUSTOM) {
|
||||
return ncurses_colors[nccolor];
|
||||
}
|
||||
return error_colour;
|
||||
return ERROR_COLOUR;
|
||||
}
|
||||
|
||||
display_output_ncurses::display_output_ncurses()
|
||||
@@ -179,7 +170,4 @@ void display_output_ncurses::flush() {
|
||||
refresh();
|
||||
clear();
|
||||
}
|
||||
|
||||
#endif /* BUILD_NCURSES */
|
||||
|
||||
} // namespace conky
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#ifndef DISPLAY_NCURSES_HH
|
||||
#define DISPLAY_NCURSES_HH
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "display-output.hh"
|
||||
#include "logging.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -35,28 +34,37 @@
|
||||
#include <unordered_map>
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
|
||||
typedef std::unordered_map<std::string, display_output_base *>
|
||||
display_outputs_t;
|
||||
|
||||
/*
|
||||
* We cannot construct this object statically, because order of object
|
||||
* construction in different modules is not defined, so register_source could be
|
||||
* called before this object is constructed. Therefore, we create it on the
|
||||
* first call to register_source.
|
||||
*/
|
||||
display_outputs_t *display_outputs;
|
||||
|
||||
} // namespace
|
||||
|
||||
// HACK: force the linker to link all the objects in with test enabled
|
||||
extern void init_console_output();
|
||||
extern void init_ncurses_output();
|
||||
extern void init_file_output();
|
||||
extern void init_http_output();
|
||||
extern void init_x11_output();
|
||||
extern void init_wayland_output();
|
||||
inline void log_missing(const char *name, const char *flag) {
|
||||
DBGP(
|
||||
"%s display output disabled. Enable by recompiling with '%s' "
|
||||
"flag enabled.",
|
||||
name, flag);
|
||||
}
|
||||
#ifndef BUILD_HTTP
|
||||
template <>
|
||||
void register_output<output_t::HTTP>(display_outputs_t &outputs) {
|
||||
log_missing("HTTP", "BUILD_HTTP");
|
||||
}
|
||||
#endif
|
||||
#ifndef BUILD_NCURSES
|
||||
template <>
|
||||
void register_output<output_t::NCURSES>(display_outputs_t &outputs) {
|
||||
log_missing("ncurses", "BUILD_NCURSES");
|
||||
}
|
||||
#endif
|
||||
#ifndef BUILD_WAYLAND
|
||||
template <>
|
||||
void register_output<output_t::WAYLAND>(display_outputs_t &outputs) {
|
||||
log_missing("Wayland", "BUILD_WAYLAND");
|
||||
}
|
||||
#endif
|
||||
#ifndef BUILD_X11
|
||||
template <>
|
||||
void register_output<output_t::X11>(display_outputs_t &outputs) {
|
||||
log_missing("X11", "BUILD_X11");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The selected and active display output.
|
||||
@@ -69,55 +77,18 @@ std::vector<display_output_base *> active_display_outputs;
|
||||
*/
|
||||
std::vector<conky::display_output_base *> current_display_outputs;
|
||||
|
||||
namespace priv {
|
||||
void do_register_display_output(const std::string &name,
|
||||
display_output_base *output) {
|
||||
struct display_output_constructor {
|
||||
display_output_constructor() { display_outputs = new display_outputs_t(); }
|
||||
~display_output_constructor() {
|
||||
delete display_outputs;
|
||||
display_outputs = nullptr;
|
||||
}
|
||||
};
|
||||
static display_output_constructor constructor;
|
||||
|
||||
bool inserted = display_outputs->insert({name, output}).second;
|
||||
if (!inserted) {
|
||||
throw std::logic_error("Display output with name '" + name +
|
||||
"' already registered");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
display_output_base::display_output_base(const std::string &name_)
|
||||
: name(name_), is_active(false), is_graphical(false), priority(-1) {
|
||||
priv::do_register_display_output(name, this);
|
||||
}
|
||||
|
||||
disabled_display_output::disabled_display_output(const std::string &name,
|
||||
const std::string &define)
|
||||
: display_output_base(name) {
|
||||
priority = -2;
|
||||
// XXX some generic way of reporting errors? NORM_ERR?
|
||||
DBGP(
|
||||
"Support for display output '%s' has been disabled during compilation. "
|
||||
"Please recompile with '%s'",
|
||||
name.c_str(), define.c_str());
|
||||
}
|
||||
|
||||
bool initialize_display_outputs() {
|
||||
init_console_output();
|
||||
init_ncurses_output();
|
||||
init_file_output();
|
||||
init_http_output();
|
||||
init_x11_output();
|
||||
init_wayland_output();
|
||||
|
||||
std::vector<display_output_base *> outputs;
|
||||
outputs.reserve(display_outputs->size());
|
||||
outputs.reserve(static_cast<size_t>(output_t::OUTPUT_COUNT));
|
||||
register_output<output_t::CONSOLE>(outputs);
|
||||
register_output<output_t::NCURSES>(outputs);
|
||||
register_output<output_t::FILE>(outputs);
|
||||
register_output<output_t::HTTP>(outputs);
|
||||
register_output<output_t::X11>(outputs);
|
||||
register_output<output_t::WAYLAND>(outputs);
|
||||
|
||||
for (auto out : outputs) { NORM_ERR("FOUND: %s", out->name.c_str()); }
|
||||
|
||||
for (auto &output : *display_outputs) { outputs.push_back(output.second); }
|
||||
// Sort display outputs by descending priority, to try graphical ones first.
|
||||
sort(outputs.begin(), outputs.end(), &display_output_base::priority_compare);
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "colours.h"
|
||||
#include "logging.h"
|
||||
#include "luamm.hh"
|
||||
|
||||
namespace conky {
|
||||
@@ -57,11 +58,11 @@ class display_output_base {
|
||||
|
||||
public:
|
||||
const std::string name;
|
||||
bool is_active;
|
||||
bool is_graphical;
|
||||
int priority;
|
||||
bool is_active = false;
|
||||
bool is_graphical = false;
|
||||
int priority = -1;
|
||||
|
||||
explicit display_output_base(const std::string &name_);
|
||||
explicit display_output_base(const std::string &name) : name(name){};
|
||||
|
||||
virtual ~display_output_base() {}
|
||||
|
||||
@@ -106,7 +107,11 @@ class display_output_base {
|
||||
virtual void draw_arc(int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*a1*/,
|
||||
int /*a2*/) {}
|
||||
virtual void move_win(int /*x*/, int /*y*/) {}
|
||||
virtual int dpi_scale(int value) { return value; }
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
std::is_arithmetic<T>::value, T>::type>
|
||||
T dpi_scale(T value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
virtual void begin_draw_stuff() {}
|
||||
virtual void end_draw_stuff() {}
|
||||
@@ -137,6 +142,20 @@ class display_output_base {
|
||||
virtual bool active() { return is_active; }
|
||||
};
|
||||
|
||||
using display_outputs_t = std::vector<display_output_base *>;
|
||||
|
||||
enum class output_t : uint32_t {
|
||||
CONSOLE,
|
||||
NCURSES,
|
||||
FILE,
|
||||
HTTP,
|
||||
X11,
|
||||
WAYLAND,
|
||||
OUTPUT_COUNT
|
||||
};
|
||||
template <output_t Output>
|
||||
void register_output(display_outputs_t &outputs);
|
||||
|
||||
/*
|
||||
* The selected and active display outputs.
|
||||
*/
|
||||
@@ -148,17 +167,6 @@ extern std::vector<display_output_base *> active_display_outputs;
|
||||
*/
|
||||
extern std::vector<conky::display_output_base *> current_display_outputs;
|
||||
|
||||
/*
|
||||
* Use this to declare a display output that has been disabled during
|
||||
* compilation. We can then print a nice error message telling the used which
|
||||
* setting to enable.
|
||||
*/
|
||||
class disabled_display_output : public display_output_base {
|
||||
public:
|
||||
const std::string define;
|
||||
disabled_display_output(const std::string &name, const std::string &define);
|
||||
};
|
||||
|
||||
} // namespace conky
|
||||
|
||||
// XXX: move to namespace?
|
||||
@@ -178,6 +186,21 @@ static inline conky::display_output_base *display_output() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
std::is_arithmetic<T>::value, T>::type>
|
||||
inline T dpi_scale(T value) {
|
||||
#ifdef BUILD_GUI
|
||||
auto output = display_output();
|
||||
if (output) {
|
||||
return output->dpi_scale(value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
#else /* BUILD_GUI */
|
||||
return value;
|
||||
#endif /* BUILD_GUI */
|
||||
}
|
||||
|
||||
static inline void unset_display_output() {
|
||||
conky::current_display_outputs.clear();
|
||||
}
|
||||
|
@@ -24,9 +24,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "display-wayland.hh"
|
||||
|
||||
#ifdef BUILD_WAYLAND
|
||||
#include <wayland-client.h>
|
||||
// #include "wayland.h"
|
||||
#include <cairo.h>
|
||||
@@ -44,23 +43,18 @@
|
||||
#include <wlr-layer-shell-client-protocol.h>
|
||||
#include <xdg-shell-client-protocol.h>
|
||||
|
||||
#endif /* BUILD_WAYLAND */
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "conky.h"
|
||||
#include "display-wayland.hh"
|
||||
#include "display-output.hh"
|
||||
#include "gui.h"
|
||||
#include "llua.h"
|
||||
#include "logging.h"
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
#endif
|
||||
#ifdef BUILD_WAYLAND
|
||||
|
||||
#include "fonts.h"
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
#include <array>
|
||||
#include <map>
|
||||
@@ -69,9 +63,6 @@
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/* TODO: cleanup global namespace */
|
||||
#ifdef BUILD_WAYLAND
|
||||
|
||||
static int set_cloexec_or_close(int fd) {
|
||||
long flags;
|
||||
|
||||
@@ -238,24 +229,15 @@ static void wayland_create_window() {
|
||||
update_text_area(); /* to get initial size of the window */
|
||||
}
|
||||
|
||||
#endif /* BUILD_WAYLAND */
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
|
||||
#ifdef BUILD_WAYLAND
|
||||
conky::display_output_wayland wayland_output;
|
||||
#else
|
||||
conky::disabled_display_output wayland_output_disabled("wayland",
|
||||
"BUILD_WAYLAND");
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
extern void init_wayland_output() {}
|
||||
|
||||
namespace priv {} // namespace priv
|
||||
|
||||
#ifdef BUILD_WAYLAND
|
||||
template <>
|
||||
void register_output<output_t::WAYLAND>(display_outputs_t &outputs) {
|
||||
outputs.push_back(&wayland_output);
|
||||
}
|
||||
|
||||
display_output_wayland::display_output_wayland()
|
||||
: display_output_base("wayland") {
|
||||
@@ -489,7 +471,11 @@ static void on_pointer_button(void *data, struct wl_pointer *pointer,
|
||||
size_t abs_y = w->rectangle.y + y;
|
||||
|
||||
mouse_button_event event{
|
||||
mouse_event_t::MOUSE_RELEASE, x, y, abs_x, abs_y,
|
||||
mouse_event_t::RELEASE,
|
||||
x,
|
||||
y,
|
||||
abs_x,
|
||||
abs_y,
|
||||
static_cast<mouse_button_t>(button),
|
||||
};
|
||||
|
||||
@@ -498,7 +484,7 @@ static void on_pointer_button(void *data, struct wl_pointer *pointer,
|
||||
// pass; default is MOUSE_RELEASE
|
||||
break;
|
||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||
event.type = mouse_event_t::MOUSE_PRESS;
|
||||
event.type = mouse_event_t::PRESS;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -519,17 +505,17 @@ void on_pointer_axis(void *data, struct wl_pointer *pointer, std::uint32_t time,
|
||||
size_t abs_y = w->rectangle.y + y;
|
||||
|
||||
mouse_scroll_event event{
|
||||
x, y, abs_x, abs_y, scroll_direction_t::SCROLL_UP,
|
||||
x, y, abs_x, abs_y, scroll_direction_t::UP,
|
||||
};
|
||||
|
||||
switch (static_cast<wl_pointer_axis>(axis)) {
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
event.direction = value > 0 ? scroll_direction_t::SCROLL_DOWN
|
||||
: scroll_direction_t::SCROLL_UP;
|
||||
event.direction =
|
||||
value > 0 ? scroll_direction_t::DOWN : scroll_direction_t::UP;
|
||||
break;
|
||||
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
|
||||
event.direction = value > 0 ? scroll_direction_t::SCROLL_RIGHT
|
||||
: scroll_direction_t::SCROLL_LEFT;
|
||||
event.direction =
|
||||
value > 0 ? scroll_direction_t::RIGHT : scroll_direction_t::LEFT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -577,7 +563,9 @@ bool display_output_wayland::initialize() {
|
||||
|
||||
wl_display_roundtrip(global_display);
|
||||
if (wl_globals.layer_shell == nullptr) {
|
||||
CRIT_ERR("Compositor doesn't support wlr-layer-shell-unstable-v1. Can't run conky.");
|
||||
CRIT_ERR(
|
||||
"Compositor doesn't support wlr-layer-shell-unstable-v1. Can't run "
|
||||
"conky.");
|
||||
}
|
||||
|
||||
struct wl_surface *surface =
|
||||
@@ -705,48 +693,34 @@ bool display_output_wayland::main_loop_wait(double t) {
|
||||
|
||||
/* update struts */
|
||||
if (changed != 0) {
|
||||
int anchor = -1;
|
||||
int anchor = 0;
|
||||
|
||||
DBGP("%s", _(PACKAGE_NAME ": defining struts\n"));
|
||||
fflush(stderr);
|
||||
|
||||
switch (text_alignment.get(*state)) {
|
||||
case TOP_LEFT:
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||
alignment text_align = text_alignment.get(*state);
|
||||
switch (vertical_alignment(text_align)) {
|
||||
case axis_align::START:
|
||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||
break;
|
||||
case TOP_RIGHT:
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
case axis_align::END:
|
||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||
break;
|
||||
case TOP_MIDDLE: {
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case BOTTOM_LEFT:
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||
break;
|
||||
case BOTTOM_RIGHT:
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
break;
|
||||
case BOTTOM_MIDDLE: {
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||
break;
|
||||
}
|
||||
case MIDDLE_LEFT: {
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||
break;
|
||||
}
|
||||
case MIDDLE_RIGHT: {
|
||||
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
case NONE:
|
||||
case MIDDLE_MIDDLE: /* XXX What about these? */;
|
||||
}
|
||||
switch (horizontal_alignment(text_align)) {
|
||||
case axis_align::START:
|
||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||
break;
|
||||
case axis_align::END:
|
||||
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// middle anchor alignment is the default and requires no special
|
||||
// handling.
|
||||
|
||||
if (anchor != -1) {
|
||||
zwlr_layer_surface_v1_set_anchor(global_window->layer_surface, anchor);
|
||||
@@ -939,8 +913,10 @@ void display_output_wayland::move_win(int x, int y) {
|
||||
// window.y = y;
|
||||
// TODO
|
||||
}
|
||||
|
||||
int display_output_wayland::dpi_scale(int value) { return value; }
|
||||
template <typename T, typename>
|
||||
T display_output_wayland::dpi_scale(T value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
void display_output_wayland::end_draw_stuff() {
|
||||
window_commit_buffer(global_window);
|
||||
@@ -1292,6 +1268,4 @@ void window_get_width_height(struct window *window, int *w, int *h) {
|
||||
*h = window->rectangle.height;
|
||||
}
|
||||
|
||||
#endif /* BUILD_WAYLAND */
|
||||
|
||||
} // namespace conky
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#ifndef DISPLAY_WAYLAND_HH
|
||||
#define DISPLAY_WAYLAND_HH
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@@ -69,7 +71,9 @@ class display_output_wayland : public display_output_base {
|
||||
virtual void fill_rect(int, int, int, int);
|
||||
virtual void draw_arc(int, int, int, int, int, int);
|
||||
virtual void move_win(int, int);
|
||||
virtual int dpi_scale(int);
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
std::is_arithmetic<T>::value, T>::type>
|
||||
T dpi_scale(T value);
|
||||
|
||||
virtual void end_draw_stuff();
|
||||
virtual void clear_text(int);
|
||||
|
@@ -24,10 +24,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <X11/extensions/XI2.h>
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include <X11/X.h>
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
@@ -43,13 +41,14 @@
|
||||
#ifdef BUILD_IMLIB2
|
||||
#include "conky-imlib2.h"
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
#if defined(BUILD_MOUSE_EVENTS) || defined(BUILD_XINPUT)
|
||||
#include "mouse-events.h"
|
||||
#endif /* BUILD_MOUSE_EVENTS || BUILD_XINPUT */
|
||||
#ifdef BUILD_XINPUT
|
||||
#include <X11/extensions/XI2.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#undef COUNT
|
||||
#endif /* BUILD_XINPUT */
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
@@ -65,9 +64,6 @@
|
||||
#include "gui.h"
|
||||
#include "llua.h"
|
||||
|
||||
/* TODO: cleanup global namespace */
|
||||
#ifdef BUILD_X11
|
||||
|
||||
#include "logging.h"
|
||||
#include "x11.h"
|
||||
|
||||
@@ -195,23 +191,15 @@ static void X11_create_window() {
|
||||
update_text_area(); /* to get initial size of the window */
|
||||
}
|
||||
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
namespace conky {
|
||||
namespace {
|
||||
|
||||
#ifdef BUILD_X11
|
||||
conky::display_output_x11 x11_output;
|
||||
#else
|
||||
conky::disabled_display_output x11_output_disabled("x11", "BUILD_X11");
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
extern void init_x11_output() {}
|
||||
|
||||
namespace priv {} // namespace priv
|
||||
|
||||
#ifdef BUILD_X11
|
||||
template <>
|
||||
void register_output<output_t::X11>(display_outputs_t &outputs) {
|
||||
outputs.push_back(&x11_output);
|
||||
}
|
||||
|
||||
display_output_x11::display_output_x11() : display_output_base("x11") {
|
||||
is_graphical = true;
|
||||
@@ -324,39 +312,38 @@ bool display_output_x11::main_loop_wait(double t) {
|
||||
}
|
||||
|
||||
/* update struts */
|
||||
if ((changed != 0) && own_window_type.get(*state) == TYPE_PANEL) {
|
||||
if ((changed != 0) && own_window_type.get(*state) == window_type::PANEL) {
|
||||
int sidenum = -1;
|
||||
|
||||
DBGP("%s", _(PACKAGE_NAME ": defining struts\n"));
|
||||
fflush(stderr);
|
||||
NORM_ERR("defining struts");
|
||||
|
||||
switch (text_alignment.get(*state)) {
|
||||
case TOP_LEFT:
|
||||
case TOP_RIGHT:
|
||||
case TOP_MIDDLE: {
|
||||
alignment align = text_alignment.get(*state);
|
||||
switch (align) {
|
||||
case alignment::TOP_LEFT:
|
||||
case alignment::TOP_RIGHT:
|
||||
case alignment::TOP_MIDDLE: {
|
||||
sidenum = 2;
|
||||
break;
|
||||
}
|
||||
case BOTTOM_LEFT:
|
||||
case BOTTOM_RIGHT:
|
||||
case BOTTOM_MIDDLE: {
|
||||
case alignment::BOTTOM_LEFT:
|
||||
case alignment::BOTTOM_RIGHT:
|
||||
case alignment::BOTTOM_MIDDLE: {
|
||||
sidenum = 3;
|
||||
break;
|
||||
}
|
||||
case MIDDLE_LEFT: {
|
||||
case alignment::MIDDLE_LEFT: {
|
||||
sidenum = 0;
|
||||
break;
|
||||
}
|
||||
case MIDDLE_RIGHT: {
|
||||
case alignment::MIDDLE_RIGHT: {
|
||||
sidenum = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case NONE:
|
||||
case MIDDLE_MIDDLE: /* XXX What about these? */;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
set_struts(sidenum);
|
||||
if (sidenum != -1) set_struts(sidenum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -425,11 +412,10 @@ bool display_output_x11::main_loop_wait(double t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
enum x_event_handler {
|
||||
enum class x_event_handler {
|
||||
XINPUT_MOTION,
|
||||
MOUSE_INPUT,
|
||||
PROPERTY_NOTIFY,
|
||||
|
||||
EXPOSE,
|
||||
REPARENT,
|
||||
CONFIGURE,
|
||||
@@ -485,8 +471,6 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
|
||||
|
||||
Window event_window =
|
||||
query_x11_window_at_pos(display, data->root_x, data->root_y);
|
||||
// query_result is not window.window in some cases.
|
||||
modifier_state_t mods = x11_modifier_state(data->mods.effective);
|
||||
|
||||
bool same_window = query_x11_top_parent(display, event_window) ==
|
||||
query_x11_top_parent(display, window.window);
|
||||
@@ -518,6 +502,10 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
// query_result is not window.window in some cases.
|
||||
modifier_state_t mods = x11_modifier_state(data->mods.effective);
|
||||
|
||||
if (data->evtype == XI_Motion) {
|
||||
// TODO: Make valuator_index names configurable?
|
||||
|
||||
@@ -556,20 +544,18 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
|
||||
double vertical_value = vertical.value_or(0.0);
|
||||
|
||||
if (vertical_value != 0.0) {
|
||||
scroll_direction = vertical_value < 0.0
|
||||
? scroll_direction_t::SCROLL_UP
|
||||
: scroll_direction_t::SCROLL_DOWN;
|
||||
scroll_direction = vertical_value < 0.0 ? scroll_direction_t::UP
|
||||
: scroll_direction_t::DOWN;
|
||||
} else {
|
||||
auto horizontal = data->valuator_relative_value(valuator_t::SCROLL_X);
|
||||
double horizontal_value = horizontal.value_or(0.0);
|
||||
if (horizontal_value != 0.0) {
|
||||
scroll_direction = horizontal_value < 0.0
|
||||
? scroll_direction_t::SCROLL_LEFT
|
||||
: scroll_direction_t::SCROLL_RIGHT;
|
||||
scroll_direction = horizontal_value < 0.0 ? scroll_direction_t::LEFT
|
||||
: scroll_direction_t::RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
if (scroll_direction != scroll_direction_t::SCROLL_UNKNOWN) {
|
||||
if (scroll_direction != scroll_direction_t::UNKNOWN) {
|
||||
*consumed = llua_mouse_hook(
|
||||
mouse_scroll_event(data->event_x, data->event_y, data->root_x,
|
||||
data->root_y, scroll_direction, mods));
|
||||
@@ -583,16 +569,16 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
|
||||
return true;
|
||||
}
|
||||
|
||||
mouse_event_t type = mouse_event_t::MOUSE_PRESS;
|
||||
if (data->evtype == XI_ButtonRelease) {
|
||||
type = mouse_event_t::MOUSE_RELEASE;
|
||||
}
|
||||
mouse_event_t type = mouse_event_t::PRESS;
|
||||
if (data->evtype == XI_ButtonRelease) { type = mouse_event_t::RELEASE; }
|
||||
|
||||
mouse_button_t button = x11_mouse_button_code(data->detail);
|
||||
*consumed = llua_mouse_hook(mouse_button_event(type, data->event_x,
|
||||
data->event_y, data->root_x,
|
||||
data->root_y, button, mods));
|
||||
}
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
|
||||
#else /* BUILD_XINPUT */
|
||||
if (ev.type != ButtonPress && ev.type != ButtonRelease &&
|
||||
ev.type != MotionNotify)
|
||||
@@ -612,9 +598,10 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
|
||||
} else {
|
||||
mouse_button_t button = x11_mouse_button_code(ev.xbutton.button);
|
||||
*consumed = llua_mouse_hook(mouse_button_event(
|
||||
mouse_event_t::MOUSE_PRESS, ev.xbutton.x, ev.xbutton.y,
|
||||
ev.xbutton.x_root, ev.xbutton.y_root, button, mods));
|
||||
mouse_event_t::PRESS, ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root,
|
||||
ev.xbutton.y_root, button, mods));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ButtonRelease: {
|
||||
/* don't report scroll release events */
|
||||
@@ -623,31 +610,35 @@ bool handle_event<x_event_handler::MOUSE_INPUT>(
|
||||
modifier_state_t mods = x11_modifier_state(ev.xbutton.state);
|
||||
mouse_button_t button = x11_mouse_button_code(ev.xbutton.button);
|
||||
*consumed = llua_mouse_hook(mouse_button_event(
|
||||
mouse_event_t::MOUSE_RELEASE, ev.xbutton.x, ev.xbutton.y,
|
||||
ev.xbutton.x_root, ev.xbutton.y_root, button, mods));
|
||||
mouse_event_t::RELEASE, ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root,
|
||||
ev.xbutton.y_root, button, mods));
|
||||
break;
|
||||
}
|
||||
case MotionNotify: {
|
||||
modifier_state_t mods = x11_modifier_state(ev.xmotion.state);
|
||||
*consumed = llua_mouse_hook(mouse_move_event(ev.xmotion.x, ev.xmotion.y,
|
||||
ev.xmotion.x_root,
|
||||
ev.xmotion.y_root, mods));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_XINPUT */
|
||||
#ifndef BUILD_MOUSE_EVENTS
|
||||
// always propagate mouse input if not handling mouse events
|
||||
*consumed = false;
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_XINPUT */
|
||||
|
||||
if (!own_window.get(*state)) return true;
|
||||
switch (own_window_type.get(*state)) {
|
||||
case window_type::TYPE_NORMAL:
|
||||
case window_type::TYPE_UTILITY:
|
||||
case window_type::NORMAL:
|
||||
case window_type::UTILITY:
|
||||
// decorated normal windows always consume events
|
||||
if (!TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) {
|
||||
if (!TEST_HINT(own_window_hints.get(*state), window_hints::UNDECORATED)) {
|
||||
*consumed = true;
|
||||
}
|
||||
break;
|
||||
case window_type::TYPE_DESKTOP:
|
||||
case window_type::DESKTOP:
|
||||
// assume conky is always on bottom; nothing to propagate events to
|
||||
*consumed = true;
|
||||
default:
|
||||
@@ -714,6 +705,31 @@ bool handle_event<x_event_handler::CONFIGURE>(
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
template <>
|
||||
bool handle_event<x_event_handler::BORDER_CROSSING>(
|
||||
conky::display_output_x11 *surface, Display *display, XEvent &ev,
|
||||
bool *consumed, void **cookie) {
|
||||
if (ev.type != EnterNotify && ev.type != LeaveNotify) return false;
|
||||
if (window.xi_opcode != 0) return true; // handled by mouse_input already
|
||||
|
||||
bool not_over_conky = ev.xcrossing.x_root <= window.x ||
|
||||
ev.xcrossing.y_root <= window.y ||
|
||||
ev.xcrossing.x_root >= window.x + window.width ||
|
||||
ev.xcrossing.y_root >= window.y + window.height;
|
||||
|
||||
if ((not_over_conky && ev.xcrossing.type == LeaveNotify) ||
|
||||
(!not_over_conky && ev.xcrossing.type == EnterNotify)) {
|
||||
llua_mouse_hook(mouse_crossing_event(
|
||||
ev.xcrossing.type == EnterNotify ? mouse_event_t::AREA_ENTER
|
||||
: mouse_event_t::AREA_LEAVE,
|
||||
ev.xcrossing.x, ev.xcrossing.y, ev.xcrossing.x_root,
|
||||
ev.xcrossing.y_root));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* OWN_WINDOW */
|
||||
|
||||
template <>
|
||||
@@ -757,29 +773,6 @@ bool handle_event<x_event_handler::EXPOSE>(conky::display_output_x11 *surface,
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool handle_event<x_event_handler::BORDER_CROSSING>(
|
||||
conky::display_output_x11 *surface, Display *display, XEvent &ev,
|
||||
bool *consumed, void **cookie) {
|
||||
if (ev.type != EnterNotify && ev.type != LeaveNotify) return false;
|
||||
if (window.xi_opcode != 0) return true; // handled by mouse_input already
|
||||
|
||||
bool not_over_conky = ev.xcrossing.x_root <= window.x ||
|
||||
ev.xcrossing.y_root <= window.y ||
|
||||
ev.xcrossing.x_root >= window.x + window.width ||
|
||||
ev.xcrossing.y_root >= window.y + window.height;
|
||||
|
||||
if ((not_over_conky && ev.xcrossing.type == LeaveNotify) ||
|
||||
(!not_over_conky && ev.xcrossing.type == EnterNotify)) {
|
||||
llua_mouse_hook(mouse_crossing_event(
|
||||
ev.xcrossing.type == EnterNotify ? mouse_event_t::AREA_ENTER
|
||||
: mouse_event_t::AREA_LEAVE,
|
||||
ev.xcrossing.x, ev.xcrossing.y, ev.xcrossing.x_root,
|
||||
ev.xcrossing.y_root));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BUILD_XDAMAGE
|
||||
template <>
|
||||
bool handle_event<x_event_handler::DAMAGE>(conky::display_output_x11 *surface,
|
||||
@@ -820,6 +813,8 @@ bool process_event(conky::display_output_x11 *surface, Display *display,
|
||||
HANDLE_EV(BORDER_CROSSING)
|
||||
HANDLE_EV(DAMAGE)
|
||||
|
||||
#undef HANDLE_EV
|
||||
|
||||
// event not handled
|
||||
return false;
|
||||
}
|
||||
@@ -889,7 +884,7 @@ void display_output_x11::set_foreground_color(Colour c) {
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
XSetForeground(display, window.gc,
|
||||
current_color.to_x11_color(display, screen));
|
||||
current_color.to_x11_color(display, screen, have_argb_visual));
|
||||
}
|
||||
|
||||
int display_output_x11::calc_text_width(const char *s) {
|
||||
@@ -918,7 +913,7 @@ void display_output_x11::draw_string_at(int x, int y, const char *s, int w) {
|
||||
XColor c{};
|
||||
XftColor c2{};
|
||||
|
||||
c.pixel = current_color.to_x11_color(display, screen);
|
||||
c.pixel = current_color.to_x11_color(display, screen, have_argb_visual);
|
||||
// query color on custom colormap
|
||||
XQueryColor(display, window.colourmap, &c);
|
||||
|
||||
@@ -972,15 +967,19 @@ void display_output_x11::draw_arc(int x, int y, int w, int h, int a1, int a2) {
|
||||
}
|
||||
|
||||
void display_output_x11::move_win(int x, int y) {
|
||||
#ifdef OWN_WINDOW
|
||||
window.x = x;
|
||||
window.y = y;
|
||||
XMoveWindow(display, window.window, x, y);
|
||||
#endif /* OWN_WINDOW */
|
||||
}
|
||||
|
||||
int display_output_x11::dpi_scale(int value) {
|
||||
const size_t PIXELS_PER_INCH = 96;
|
||||
template <typename T, typename>
|
||||
T display_output_x11::dpi_scale(T value) {
|
||||
#if defined(BUILD_XFT)
|
||||
if (use_xft.get(*state) && xft_dpi > 0) {
|
||||
return (value * xft_dpi + (value > 0 ? 48 : -48)) / 96;
|
||||
return (value * xft_dpi + (value > 0 ? 48 : -48)) / PIXELS_PER_INCH;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
@@ -1171,6 +1170,4 @@ void display_output_x11::load_fonts(bool utf8) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
} // namespace conky
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#ifndef DISPLAY_X11_HH
|
||||
#define DISPLAY_X11_HH
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@@ -67,7 +69,9 @@ class display_output_x11 : public display_output_base {
|
||||
virtual void fill_rect(int, int, int, int);
|
||||
virtual void draw_arc(int, int, int, int, int, int);
|
||||
virtual void move_win(int, int);
|
||||
virtual int dpi_scale(int);
|
||||
template <typename T, typename = typename std::enable_if<
|
||||
std::is_arithmetic<T>::value, T>::type>
|
||||
T dpi_scale(T value);
|
||||
|
||||
virtual void end_draw_stuff();
|
||||
virtual void clear_text(int);
|
||||
|
78
src/gui.cc
78
src/gui.cc
@@ -32,11 +32,14 @@
|
||||
#include "config.h"
|
||||
#include "conky.h"
|
||||
#include "logging.h"
|
||||
#include "wl.h"
|
||||
|
||||
#ifdef BUILD_IMLIB2
|
||||
#include "conky-imlib2.h"
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#ifdef BUILD_WAYLAND
|
||||
#include "wl.h"
|
||||
#endif /* BUILD_WAYLAND */
|
||||
|
||||
// #ifdef BUILD_IMLIB2
|
||||
// #include "conky-imlib2.h"
|
||||
// #endif /* BUILD_IMLIB2 */
|
||||
#ifndef OWN_WINDOW
|
||||
#include <iostream>
|
||||
#endif
|
||||
@@ -103,41 +106,46 @@ void own_window_setting::lua_setter(lua::state &l, bool init) {
|
||||
|
||||
template <>
|
||||
conky::lua_traits<alignment>::Map conky::lua_traits<alignment>::map = {
|
||||
{"top_left", TOP_LEFT},
|
||||
{"top_right", TOP_RIGHT},
|
||||
{"top_middle", TOP_MIDDLE},
|
||||
{"bottom_left", BOTTOM_LEFT},
|
||||
{"bottom_right", BOTTOM_RIGHT},
|
||||
{"bottom_middle", BOTTOM_MIDDLE},
|
||||
{"middle_left", MIDDLE_LEFT},
|
||||
{"middle_middle", MIDDLE_MIDDLE},
|
||||
{"middle_right", MIDDLE_RIGHT},
|
||||
{"tl", TOP_LEFT},
|
||||
{"tr", TOP_RIGHT},
|
||||
{"tm", TOP_MIDDLE},
|
||||
{"bl", BOTTOM_LEFT},
|
||||
{"br", BOTTOM_RIGHT},
|
||||
{"bm", BOTTOM_MIDDLE},
|
||||
{"ml", MIDDLE_LEFT},
|
||||
{"mm", MIDDLE_MIDDLE},
|
||||
{"mr", MIDDLE_RIGHT},
|
||||
{"none", NONE}};
|
||||
{"top_left", alignment::TOP_LEFT},
|
||||
{"top_right", alignment::TOP_RIGHT},
|
||||
{"top_middle", alignment::TOP_MIDDLE},
|
||||
{"top", alignment::TOP_MIDDLE},
|
||||
{"bottom_left", alignment::BOTTOM_LEFT},
|
||||
{"bottom_right", alignment::BOTTOM_RIGHT},
|
||||
{"bottom_middle", alignment::BOTTOM_MIDDLE},
|
||||
{"bottom", alignment::BOTTOM_MIDDLE},
|
||||
{"middle_left", alignment::MIDDLE_LEFT},
|
||||
{"left", alignment::MIDDLE_LEFT},
|
||||
{"middle_middle", alignment::MIDDLE_MIDDLE},
|
||||
{"center", alignment::MIDDLE_MIDDLE},
|
||||
{"middle_right", alignment::MIDDLE_RIGHT},
|
||||
{"right", alignment::MIDDLE_RIGHT},
|
||||
{"tl", alignment::TOP_LEFT},
|
||||
{"tr", alignment::TOP_RIGHT},
|
||||
{"tm", alignment::TOP_MIDDLE},
|
||||
{"bl", alignment::BOTTOM_LEFT},
|
||||
{"br", alignment::BOTTOM_RIGHT},
|
||||
{"bm", alignment::BOTTOM_MIDDLE},
|
||||
{"ml", alignment::MIDDLE_LEFT},
|
||||
{"mm", alignment::MIDDLE_MIDDLE},
|
||||
{"mr", alignment::MIDDLE_RIGHT},
|
||||
{"none", alignment::NONE}};
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
template <>
|
||||
conky::lua_traits<window_type>::Map conky::lua_traits<window_type>::map = {
|
||||
{"normal", TYPE_NORMAL}, {"dock", TYPE_DOCK},
|
||||
{"panel", TYPE_PANEL}, {"desktop", TYPE_DESKTOP},
|
||||
{"utility", TYPE_UTILITY}, {"override", TYPE_OVERRIDE}};
|
||||
{"normal", window_type::NORMAL}, {"dock", window_type::DOCK},
|
||||
{"panel", window_type::PANEL}, {"desktop", window_type::DESKTOP},
|
||||
{"utility", window_type::UTILITY}, {"override", window_type::OVERRIDE}};
|
||||
|
||||
template <>
|
||||
conky::lua_traits<window_hints>::Map conky::lua_traits<window_hints>::map = {
|
||||
{"undecorated", HINT_UNDECORATED},
|
||||
{"below", HINT_BELOW},
|
||||
{"above", HINT_ABOVE},
|
||||
{"sticky", HINT_STICKY},
|
||||
{"skip_taskbar", HINT_SKIP_TASKBAR},
|
||||
{"skip_pager", HINT_SKIP_PAGER}};
|
||||
{"undecorated", window_hints::UNDECORATED},
|
||||
{"below", window_hints::BELOW},
|
||||
{"above", window_hints::ABOVE},
|
||||
{"sticky", window_hints::STICKY},
|
||||
{"skip_taskbar", window_hints::SKIP_TASKBAR},
|
||||
{"skip_pager", window_hints::SKIP_PAGER}};
|
||||
|
||||
std::pair<uint16_t, bool> window_hints_traits::convert(
|
||||
lua::state &l, int index, const std::string &name) {
|
||||
@@ -185,7 +193,8 @@ std::string gethostnamecxx() {
|
||||
* setting.cc.
|
||||
*/
|
||||
|
||||
conky::simple_config_setting<alignment> text_alignment("alignment", BOTTOM_LEFT,
|
||||
conky::simple_config_setting<alignment> text_alignment("alignment",
|
||||
alignment::BOTTOM_LEFT,
|
||||
false);
|
||||
|
||||
priv::colour_setting default_shade_color("default_shade_color", black_argb32);
|
||||
@@ -209,7 +218,8 @@ conky::simple_config_setting<std::string> own_window_title(
|
||||
conky::simple_config_setting<std::string> own_window_class("own_window_class",
|
||||
PACKAGE_NAME, false);
|
||||
conky::simple_config_setting<window_type> own_window_type("own_window_type",
|
||||
TYPE_NORMAL, false);
|
||||
window_type::NORMAL,
|
||||
false);
|
||||
conky::simple_config_setting<uint16_t, window_hints_traits> own_window_hints(
|
||||
"own_window_hints", 0, false);
|
||||
#endif /* OWN_WINDOW && BUILD_X11 */
|
||||
|
156
src/gui.h
156
src/gui.h
@@ -25,14 +25,146 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#include "colour-settings.h"
|
||||
#include "colours.h"
|
||||
#include "setting.hh"
|
||||
|
||||
#include "colour-settings.h"
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include "x11-settings.h"
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
/// @brief Represents alignment on a single axis.
|
||||
enum class axis_align : uint8_t {
|
||||
/// No alignment
|
||||
NONE = 0,
|
||||
/// Top or left alignment
|
||||
START = 0b01,
|
||||
/// Middle alignment
|
||||
MIDDLE = 0b10,
|
||||
/// Bottom or right alignment
|
||||
END = 0b11,
|
||||
};
|
||||
constexpr uint8_t operator*(axis_align index) {
|
||||
return static_cast<uint8_t>(index);
|
||||
}
|
||||
|
||||
/// @brief Represents alignment on a 2D plane.
|
||||
///
|
||||
/// Values are composed of 2 `axis_align` values: 2 bits (at 0x0C) for vertical
|
||||
/// aligment and 2 least significant bits for horizontal.
|
||||
enum class alignment : uint8_t {
|
||||
NONE = 0,
|
||||
NONE_LEFT = 0b0001,
|
||||
NONE_MIDDLE = 0b0010,
|
||||
NONE_RIGHT = 0b0011,
|
||||
TOP_LEFT = 0b0101,
|
||||
TOP_MIDDLE = 0b0110,
|
||||
TOP_RIGHT = 0b0111,
|
||||
MIDDLE_LEFT = 0b1001,
|
||||
MIDDLE_MIDDLE = 0b1010,
|
||||
MIDDLE_RIGHT = 0b1011,
|
||||
BOTTOM_LEFT = 0b1101,
|
||||
BOTTOM_MIDDLE = 0b1110,
|
||||
BOTTOM_RIGHT = 0b1111,
|
||||
};
|
||||
constexpr uint8_t operator*(alignment index) {
|
||||
return static_cast<uint8_t>(index);
|
||||
}
|
||||
|
||||
/// @brief Returns the horizontal axis alignment component of `alignment`.
|
||||
/// @param of 2D alignment to extract axis alignment from
|
||||
/// @return horizontal `axis_align`
|
||||
[[nodiscard]] inline axis_align horizontal_alignment(alignment of) {
|
||||
return static_cast<axis_align>(static_cast<uint8_t>(of) & 0b11);
|
||||
}
|
||||
/// @brief Returns the vertical axis alignment component of `alignment`.
|
||||
/// @param of 2D alignment to extract axis alignment from
|
||||
/// @return vertical `axis_align`
|
||||
[[nodiscard]] inline axis_align vertical_alignment(alignment of) {
|
||||
return static_cast<axis_align>((static_cast<uint8_t>(of) >> 2) & 0b11);
|
||||
}
|
||||
|
||||
/// @brief Describes how and where a window should be mounted, as well as its
|
||||
/// behavior.
|
||||
///
|
||||
/// We assume the following order of layers:
|
||||
/// - Background - behind conky and any other windows, contains icons and
|
||||
/// desktop menus
|
||||
/// - Background widgets and docks
|
||||
/// - Windows
|
||||
/// - Panels - contains content that covers windows
|
||||
/// - Override windows - input-override windows on X11, custom overlays, lock
|
||||
/// screens, etc.
|
||||
///
|
||||
/// See also:
|
||||
/// - [X11 wm-spec `_NET_WM_WINDOW_TYPE` property](
|
||||
/// https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html#idm45684324619328)
|
||||
/// - [wlr-layer-shell layers](
|
||||
/// https://wayland.app/protocols/wlr-layer-shell-unstable-v1#zwlr_layer_shell_v1:enum:layer)
|
||||
/// - [xdg-positioner::anchor](
|
||||
/// https://wayland.app/protocols/xdg-shell#xdg_positioner:enum:anchor)
|
||||
enum class window_type : uint8_t {
|
||||
/// @brief Acts as a normal window - has decorations, above
|
||||
/// background, widgets and docks, below panels.
|
||||
NORMAL = 0,
|
||||
/// @brief Screen background, no decorations, positioned at the very bottom
|
||||
/// and behind widgets and docks.
|
||||
DESKTOP,
|
||||
/// @brief Normal window, always shown above parent window (group).
|
||||
///
|
||||
/// See: [Popup](https://wayland.app/protocols/xdg-shell#xdg_popup) XDG shell
|
||||
/// surface.
|
||||
UTILITY,
|
||||
/// @brief No decorations, between windows and background, attached to screen
|
||||
/// edge.
|
||||
DOCK,
|
||||
/// @brief No decorations, above windows, attached to screen edge, reserves
|
||||
/// space.
|
||||
PANEL,
|
||||
#ifdef BUILD_X11
|
||||
/// @brief On top of everything else, not controlled by WM.
|
||||
OVERRIDE,
|
||||
#endif /* BUILD_X11 */
|
||||
};
|
||||
constexpr uint8_t operator*(window_type index) {
|
||||
return static_cast<uint8_t>(index);
|
||||
}
|
||||
|
||||
#if defined(BUILD_X11) && defined(OWN_WINDOW)
|
||||
// Only works in X11 because Wayland doesn't support
|
||||
|
||||
/// @brief Hints are used to tell WM how it should treat a window.
|
||||
///
|
||||
/// See: [X11 wm-spec `_NET_WM_STATE` property](
|
||||
/// https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html#idm45684324611552)
|
||||
enum class window_hints : uint16_t {
|
||||
UNDECORATED = 0,
|
||||
BELOW,
|
||||
ABOVE,
|
||||
STICKY,
|
||||
SKIP_TASKBAR,
|
||||
SKIP_PAGER
|
||||
};
|
||||
constexpr uint8_t operator*(window_hints index) {
|
||||
return static_cast<uint8_t>(index);
|
||||
}
|
||||
|
||||
inline void SET_HINT(window_hints &mask, window_hints hint) {
|
||||
mask = static_cast<window_hints>(*mask | (1 << (*hint)));
|
||||
}
|
||||
inline void SET_HINT(uint16_t &mask, window_hints hint) {
|
||||
mask = mask | (1 << (*hint));
|
||||
}
|
||||
inline bool TEST_HINT(window_hints mask, window_hints hint) {
|
||||
return (*mask & (1 << (*hint))) != 0;
|
||||
}
|
||||
inline bool TEST_HINT(uint16_t mask, window_hints hint) {
|
||||
return (mask & (1 << (*hint))) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_X11
|
||||
extern Display *display;
|
||||
#endif /* BUILD_X11 */
|
||||
@@ -70,20 +202,6 @@ void xdbe_swap_buffers(void);
|
||||
void xpmdb_swap_buffers(void);
|
||||
#endif /* BUILD_XDBE */
|
||||
|
||||
/* alignments */
|
||||
enum alignment {
|
||||
TOP_LEFT,
|
||||
TOP_RIGHT,
|
||||
TOP_MIDDLE,
|
||||
BOTTOM_LEFT,
|
||||
BOTTOM_RIGHT,
|
||||
BOTTOM_MIDDLE,
|
||||
MIDDLE_LEFT,
|
||||
MIDDLE_MIDDLE,
|
||||
MIDDLE_RIGHT,
|
||||
NONE
|
||||
};
|
||||
|
||||
extern conky::simple_config_setting<alignment> text_alignment;
|
||||
|
||||
namespace priv {
|
||||
|
@@ -27,13 +27,13 @@
|
||||
#include "conky.h"
|
||||
#include "logging.h"
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
#include "gui.h"
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
#include "gui.h"
|
||||
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
#include "mouse-events.h"
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
|
@@ -32,12 +32,9 @@ extern "C" {
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
#include "mouse-events.h"
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#define LUAPREFIX "conky_"
|
||||
|
||||
|
@@ -41,6 +41,7 @@ extern "C" {
|
||||
|
||||
namespace conky {
|
||||
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
/* Lua helper functions */
|
||||
void push_table_value(lua_State *L, std::string key, std::string value) {
|
||||
lua_pushstring(L, key.c_str());
|
||||
@@ -105,22 +106,22 @@ inline std::size_t current_time_ms() {
|
||||
void push_table_value(lua_State *L, std::string key, mouse_event_t type) {
|
||||
lua_pushstring(L, key.c_str());
|
||||
switch (type) {
|
||||
case MOUSE_PRESS:
|
||||
case mouse_event_t::PRESS:
|
||||
lua_pushstring(L, "button_down");
|
||||
break;
|
||||
case MOUSE_RELEASE:
|
||||
case mouse_event_t::RELEASE:
|
||||
lua_pushstring(L, "button_up");
|
||||
break;
|
||||
case MOUSE_SCROLL:
|
||||
case mouse_event_t::SCROLL:
|
||||
lua_pushstring(L, "mouse_scroll");
|
||||
break;
|
||||
case MOUSE_MOVE:
|
||||
case mouse_event_t::MOVE:
|
||||
lua_pushstring(L, "mouse_move");
|
||||
break;
|
||||
case AREA_ENTER:
|
||||
case mouse_event_t::AREA_ENTER:
|
||||
lua_pushstring(L, "mouse_enter");
|
||||
break;
|
||||
case AREA_LEAVE:
|
||||
case mouse_event_t::AREA_LEAVE:
|
||||
lua_pushstring(L, "mouse_leave");
|
||||
break;
|
||||
default:
|
||||
@@ -134,16 +135,16 @@ void push_table_value(lua_State *L, std::string key,
|
||||
scroll_direction_t direction) {
|
||||
lua_pushstring(L, key.c_str());
|
||||
switch (direction) {
|
||||
case SCROLL_DOWN:
|
||||
case scroll_direction_t::DOWN:
|
||||
lua_pushstring(L, "down");
|
||||
break;
|
||||
case SCROLL_UP:
|
||||
case scroll_direction_t::UP:
|
||||
lua_pushstring(L, "up");
|
||||
break;
|
||||
case SCROLL_LEFT:
|
||||
case scroll_direction_t::LEFT:
|
||||
lua_pushstring(L, "left");
|
||||
break;
|
||||
case SCROLL_RIGHT:
|
||||
case scroll_direction_t::RIGHT:
|
||||
lua_pushstring(L, "right");
|
||||
break;
|
||||
default:
|
||||
@@ -156,19 +157,19 @@ void push_table_value(lua_State *L, std::string key,
|
||||
void push_table_value(lua_State *L, std::string key, mouse_button_t button) {
|
||||
lua_pushstring(L, key.c_str());
|
||||
switch (button) {
|
||||
case BUTTON_LEFT:
|
||||
case mouse_button_t::LEFT:
|
||||
lua_pushstring(L, "left");
|
||||
break;
|
||||
case BUTTON_RIGHT:
|
||||
case mouse_button_t::RIGHT:
|
||||
lua_pushstring(L, "right");
|
||||
break;
|
||||
case BUTTON_MIDDLE:
|
||||
case mouse_button_t::MIDDLE:
|
||||
lua_pushstring(L, "middle");
|
||||
break;
|
||||
case BUTTON_BACK:
|
||||
case mouse_button_t::BACK:
|
||||
lua_pushstring(L, "back");
|
||||
break;
|
||||
case BUTTON_FORWARD:
|
||||
case mouse_button_t::FORWARD:
|
||||
lua_pushstring(L, "forward");
|
||||
break;
|
||||
default:
|
||||
@@ -213,6 +214,7 @@ void mouse_button_event::push_lua_data(lua_State *L) const {
|
||||
push_table_value(L, "button", this->button);
|
||||
push_mods(L, this->mods);
|
||||
}
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
|
||||
#ifdef BUILD_XINPUT
|
||||
/// Last global device id.
|
||||
@@ -271,10 +273,10 @@ void handle_xi_device_change(const XIHierarchyEvent *event) {
|
||||
/// some device (unlikely).
|
||||
size_t fixed_valuator_index(Display *display, XIDeviceInfo *device,
|
||||
valuator_t valuator) {
|
||||
const std::array<const char *, valuator_t::VALUATOR_COUNT> atom_names = {
|
||||
const std::array<const char *, VALUATOR_COUNT> atom_names = {
|
||||
"ConkyValuatorMoveX", "ConkyValuatorMoveY", "ConkyValuatorScrollX",
|
||||
"ConkyValuatorScrollY"};
|
||||
Atom override_atom = XInternAtom(display, atom_names[valuator], False);
|
||||
Atom override_atom = XInternAtom(display, atom_names[*valuator], False);
|
||||
unsigned char *value;
|
||||
Atom type_return;
|
||||
int format_return;
|
||||
@@ -290,7 +292,7 @@ size_t fixed_valuator_index(Display *display, XIDeviceInfo *device,
|
||||
NORM_ERR(
|
||||
"invalid '%s' option value, expected a single integer; value will "
|
||||
"be ignored",
|
||||
atom_names[valuator]);
|
||||
atom_names[*valuator]);
|
||||
XFree(value);
|
||||
break;
|
||||
}
|
||||
@@ -299,7 +301,7 @@ size_t fixed_valuator_index(Display *display, XIDeviceInfo *device,
|
||||
return static_cast<size_t>(result);
|
||||
}
|
||||
} while (true);
|
||||
return valuator;
|
||||
return *valuator;
|
||||
}
|
||||
|
||||
/// Allows override of valuator value type in `xorg.conf` in case they're wrong
|
||||
@@ -312,7 +314,7 @@ bool fixed_valuator_relative(Display *display, XIDeviceInfo *device,
|
||||
"ConkyValuatorScrollMode",
|
||||
};
|
||||
|
||||
Atom override_atom = XInternAtom(display, atom_names[valuator >> 1], False);
|
||||
Atom override_atom = XInternAtom(display, atom_names[*valuator >> 1], False);
|
||||
unsigned char *value_return;
|
||||
Atom type_return;
|
||||
int format_return;
|
||||
@@ -329,7 +331,7 @@ bool fixed_valuator_relative(Display *display, XIDeviceInfo *device,
|
||||
NORM_ERR(
|
||||
"invalid '%s' option value, expected an atom (string); value will "
|
||||
"be ignored",
|
||||
atom_names[valuator >> 1]);
|
||||
atom_names[*valuator >> 1]);
|
||||
XFree(value_return);
|
||||
break;
|
||||
}
|
||||
@@ -348,7 +350,7 @@ bool fixed_valuator_relative(Display *display, XIDeviceInfo *device,
|
||||
"unknown '%s' option value: '%s', expected 'absolute' or "
|
||||
"'relative'; "
|
||||
"value will be ignored",
|
||||
atom_names[valuator >> 1]);
|
||||
atom_names[*valuator >> 1]);
|
||||
XFree(value);
|
||||
break;
|
||||
}
|
||||
@@ -372,8 +374,8 @@ void device_info::init_xi_device(
|
||||
}
|
||||
if (device == nullptr) return;
|
||||
|
||||
std::array<size_t, valuator_t::VALUATOR_COUNT> valuator_indices;
|
||||
for (size_t i = 0; i < valuator_t::VALUATOR_COUNT; i++) {
|
||||
std::array<size_t, VALUATOR_COUNT> valuator_indices;
|
||||
for (size_t i = 0; i < VALUATOR_COUNT; i++) {
|
||||
valuator_indices[i] =
|
||||
fixed_valuator_index(display, device, static_cast<valuator_t>(i));
|
||||
}
|
||||
@@ -384,14 +386,14 @@ void device_info::init_xi_device(
|
||||
XIValuatorClassInfo *class_info = (XIValuatorClassInfo *)device->classes[i];
|
||||
|
||||
// check if one of used (mapped) valuators
|
||||
valuator_t valuator = valuator_t::VALUATOR_COUNT;
|
||||
for (size_t i = 0; i < valuator_t::VALUATOR_COUNT; i++) {
|
||||
valuator_t valuator = valuator_t::UNKNOWN;
|
||||
for (size_t i = 0; i < VALUATOR_COUNT; i++) {
|
||||
if (valuator_indices[i] == class_info->number) {
|
||||
valuator = static_cast<valuator_t>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (valuator == valuator_t::VALUATOR_COUNT) { continue; }
|
||||
if (valuator == valuator_t::UNKNOWN) { continue; }
|
||||
|
||||
auto info = conky_valuator_info{
|
||||
.index = static_cast<size_t>(class_info->number),
|
||||
@@ -402,7 +404,7 @@ void device_info::init_xi_device(
|
||||
fixed_valuator_relative(display, device, valuator, class_info),
|
||||
};
|
||||
|
||||
this->valuators[valuator] = info;
|
||||
this->valuators[*valuator] = info;
|
||||
}
|
||||
|
||||
if (std::holds_alternative<xi_device_id>(source)) {
|
||||
@@ -410,7 +412,7 @@ void device_info::init_xi_device(
|
||||
}
|
||||
}
|
||||
conky_valuator_info &device_info::valuator(valuator_t valuator) {
|
||||
return this->valuators[valuator];
|
||||
return this->valuators[*valuator];
|
||||
}
|
||||
|
||||
xi_event_data *xi_event_data::read_cookie(Display *display, const void *data) {
|
||||
@@ -460,7 +462,7 @@ xi_event_data *xi_event_data::read_cookie(Display *display, const void *data) {
|
||||
.valuators_relative = {0.0, 0.0, 0.0, 0.0},
|
||||
};
|
||||
|
||||
for (size_t v = 0; v < valuator_t::VALUATOR_COUNT; v++) {
|
||||
for (size_t v = 0; v < VALUATOR_COUNT; v++) {
|
||||
valuator_t valuator = static_cast<valuator_t>(v);
|
||||
auto &valuator_info = device->valuator(valuator);
|
||||
|
||||
@@ -497,7 +499,7 @@ std::optional<double> xi_event_data::valuator_value(valuator_t valuator) const {
|
||||
|
||||
std::optional<double> xi_event_data::valuator_relative_value(
|
||||
valuator_t valuator) const {
|
||||
return this->valuators_relative.at(valuator);
|
||||
return this->valuators_relative.at(*valuator);
|
||||
}
|
||||
|
||||
std::vector<std::tuple<int, XEvent *>> xi_event_data::generate_events(
|
||||
|
@@ -77,42 +77,50 @@ extern "C" {
|
||||
|
||||
namespace conky {
|
||||
|
||||
enum mouse_event_t {
|
||||
MOUSE_PRESS = 0,
|
||||
MOUSE_RELEASE = 1,
|
||||
MOUSE_SCROLL = 2,
|
||||
MOUSE_MOVE = 3,
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
enum class mouse_event_t : uint32_t {
|
||||
PRESS = 0,
|
||||
RELEASE = 1,
|
||||
SCROLL = 2,
|
||||
MOVE = 3,
|
||||
AREA_ENTER = 4,
|
||||
AREA_LEAVE = 5,
|
||||
MOUSE_EVENT_COUNT = 6,
|
||||
};
|
||||
const size_t MOUSE_EVENT_COUNT =
|
||||
static_cast<size_t>(mouse_event_t::AREA_LEAVE) + 1;
|
||||
constexpr uint32_t operator*(mouse_event_t index) {
|
||||
return static_cast<uint32_t>(index);
|
||||
}
|
||||
|
||||
enum mouse_button_t : std::uint32_t {
|
||||
BUTTON_LEFT = BTN_LEFT,
|
||||
BUTTON_RIGHT = BTN_RIGHT,
|
||||
BUTTON_MIDDLE = BTN_MIDDLE,
|
||||
BUTTON_BACK = BTN_BACK,
|
||||
BUTTON_FORWARD = BTN_FORWARD,
|
||||
enum class mouse_button_t : uint32_t {
|
||||
LEFT = BTN_LEFT,
|
||||
RIGHT = BTN_RIGHT,
|
||||
MIDDLE = BTN_MIDDLE,
|
||||
BACK = BTN_BACK,
|
||||
FORWARD = BTN_FORWARD,
|
||||
};
|
||||
constexpr uint32_t operator*(mouse_button_t index) {
|
||||
return static_cast<uint32_t>(index);
|
||||
}
|
||||
|
||||
#ifdef BUILD_X11
|
||||
inline mouse_button_t x11_mouse_button_code(unsigned int x11_mouse_button) {
|
||||
mouse_button_t button;
|
||||
switch (x11_mouse_button) {
|
||||
case Button1:
|
||||
button = BUTTON_LEFT;
|
||||
button = mouse_button_t::LEFT;
|
||||
break;
|
||||
case Button2:
|
||||
button = BUTTON_MIDDLE;
|
||||
button = mouse_button_t::MIDDLE;
|
||||
break;
|
||||
case Button3:
|
||||
button = BUTTON_RIGHT;
|
||||
button = mouse_button_t::RIGHT;
|
||||
break;
|
||||
case 8:
|
||||
button = BUTTON_BACK;
|
||||
button = mouse_button_t::BACK;
|
||||
break;
|
||||
case 9:
|
||||
button = BUTTON_FORWARD;
|
||||
button = mouse_button_t::FORWARD;
|
||||
break;
|
||||
default:
|
||||
DBGP("X11 button %d is not mapped", x11_mouse_button);
|
||||
@@ -145,26 +153,29 @@ struct mouse_positioned_event : public mouse_event {
|
||||
};
|
||||
|
||||
typedef std::bitset<6> modifier_state_t;
|
||||
enum modifier_key : std::uint32_t {
|
||||
MOD_SHIFT = 0,
|
||||
MOD_CONTROL = 1,
|
||||
MOD_ALT = 2,
|
||||
enum class modifier_key : uint32_t {
|
||||
SHIFT = 0,
|
||||
CONTROL = 1,
|
||||
ALT = 2,
|
||||
// Windows/MacOS key on most keyboards
|
||||
MOD_SUPER = 3,
|
||||
MOD_CAPS_LOCK = 4,
|
||||
MOD_NUM_LOCK = 5,
|
||||
SUPER = 3,
|
||||
CAPS_LOCK = 4,
|
||||
NUM_LOCK = 5,
|
||||
};
|
||||
constexpr uint32_t operator*(modifier_key index) {
|
||||
return static_cast<uint32_t>(index);
|
||||
}
|
||||
std::string modifier_name(modifier_key key);
|
||||
|
||||
#ifdef BUILD_X11
|
||||
inline modifier_state_t x11_modifier_state(unsigned int mods) {
|
||||
modifier_state_t result;
|
||||
result[MOD_SHIFT] = mods & ShiftMask;
|
||||
result[MOD_CONTROL] = mods & ControlMask;
|
||||
result[MOD_ALT] = mods & Mod1Mask;
|
||||
result[MOD_SUPER] = mods & Mod4Mask;
|
||||
result[MOD_CAPS_LOCK] = mods & LockMask;
|
||||
result[MOD_NUM_LOCK] = mods & Mod2Mask;
|
||||
result[*modifier_key::SHIFT] = mods & ShiftMask;
|
||||
result[*modifier_key::CONTROL] = mods & ControlMask;
|
||||
result[*modifier_key::ALT] = mods & Mod1Mask;
|
||||
result[*modifier_key::SUPER] = mods & Mod4Mask;
|
||||
result[*modifier_key::CAPS_LOCK] = mods & LockMask;
|
||||
result[*modifier_key::NUM_LOCK] = mods & Mod2Mask;
|
||||
return result;
|
||||
}
|
||||
#endif /* BUILD_X11 */
|
||||
@@ -174,35 +185,38 @@ struct mouse_move_event : public mouse_positioned_event {
|
||||
|
||||
mouse_move_event(std::size_t x, std::size_t y, std::size_t x_abs,
|
||||
std::size_t y_abs, modifier_state_t mods = 0)
|
||||
: mouse_positioned_event{mouse_event_t::MOUSE_MOVE, x, y, x_abs, y_abs},
|
||||
: mouse_positioned_event{mouse_event_t::MOVE, x, y, x_abs, y_abs},
|
||||
mods(mods){};
|
||||
|
||||
void push_lua_data(lua_State *L) const;
|
||||
};
|
||||
|
||||
enum scroll_direction_t : std::uint8_t {
|
||||
SCROLL_UNKNOWN = 0,
|
||||
SCROLL_UP,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_LEFT,
|
||||
SCROLL_RIGHT,
|
||||
enum class scroll_direction_t : uint8_t {
|
||||
UNKNOWN = 0,
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
};
|
||||
constexpr uint8_t operator*(scroll_direction_t index) {
|
||||
return static_cast<uint8_t>(index);
|
||||
}
|
||||
|
||||
#ifdef BUILD_X11
|
||||
inline scroll_direction_t x11_scroll_direction(unsigned int x11_mouse_button) {
|
||||
scroll_direction_t direction = SCROLL_UNKNOWN;
|
||||
scroll_direction_t direction = scroll_direction_t::UNKNOWN;
|
||||
switch (x11_mouse_button) {
|
||||
case Button4:
|
||||
direction = SCROLL_UP;
|
||||
direction = scroll_direction_t::UP;
|
||||
break;
|
||||
case Button5:
|
||||
direction = SCROLL_DOWN;
|
||||
direction = scroll_direction_t::DOWN;
|
||||
break;
|
||||
case 6:
|
||||
direction = SCROLL_LEFT;
|
||||
direction = scroll_direction_t::LEFT;
|
||||
break;
|
||||
case 7:
|
||||
direction = SCROLL_RIGHT;
|
||||
direction = scroll_direction_t::RIGHT;
|
||||
break;
|
||||
}
|
||||
return direction;
|
||||
@@ -216,7 +230,7 @@ struct mouse_scroll_event : public mouse_positioned_event {
|
||||
mouse_scroll_event(std::size_t x, std::size_t y, std::size_t x_abs,
|
||||
std::size_t y_abs, scroll_direction_t direction,
|
||||
modifier_state_t mods = 0)
|
||||
: mouse_positioned_event{mouse_event_t::MOUSE_SCROLL, x, y, x_abs, y_abs},
|
||||
: mouse_positioned_event{mouse_event_t::SCROLL, x, y, x_abs, y_abs},
|
||||
direction(direction),
|
||||
mods(mods){};
|
||||
|
||||
@@ -242,12 +256,17 @@ struct mouse_crossing_event : public mouse_positioned_event {
|
||||
std::size_t x_abs, std::size_t y_abs)
|
||||
: mouse_positioned_event{type, x, y, x_abs, y_abs} {};
|
||||
};
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
|
||||
#ifdef BUILD_XINPUT
|
||||
typedef int xi_device_id;
|
||||
typedef int xi_event_type;
|
||||
|
||||
enum valuator_t : size_t { MOVE_X, MOVE_Y, SCROLL_X, SCROLL_Y, VALUATOR_COUNT };
|
||||
enum class valuator_t : size_t { MOVE_X, MOVE_Y, SCROLL_X, SCROLL_Y, UNKNOWN };
|
||||
const size_t VALUATOR_COUNT = static_cast<size_t>(valuator_t::UNKNOWN);
|
||||
constexpr uint8_t operator*(valuator_t index) {
|
||||
return static_cast<uint8_t>(index);
|
||||
}
|
||||
|
||||
struct conky_valuator_info {
|
||||
size_t index;
|
||||
@@ -261,7 +280,7 @@ struct device_info {
|
||||
/// @brief Device name.
|
||||
xi_device_id id;
|
||||
std::string name;
|
||||
std::array<conky_valuator_info, valuator_t::VALUATOR_COUNT> valuators{};
|
||||
std::array<conky_valuator_info, VALUATOR_COUNT> valuators{};
|
||||
|
||||
static device_info *from_xi_id(xi_device_id id, Display *display = nullptr);
|
||||
|
||||
@@ -305,7 +324,7 @@ struct xi_event_data {
|
||||
// Extra data
|
||||
|
||||
/// Precomputed relative values
|
||||
std::array<double, valuator_t::VALUATOR_COUNT> valuators_relative;
|
||||
std::array<double, VALUATOR_COUNT> valuators_relative;
|
||||
|
||||
static xi_event_data *read_cookie(Display *display, const void *data);
|
||||
|
||||
|
@@ -99,6 +99,8 @@
|
||||
#include "conky.h"
|
||||
#include "logging.h"
|
||||
#include "temphelper.h"
|
||||
|
||||
// Current implementation uses X11 specific system utils
|
||||
#include "x11.h"
|
||||
|
||||
#include <memory>
|
||||
@@ -422,7 +424,7 @@ nvidia_display_setting nvidia_display;
|
||||
|
||||
// Evaluate module parameters and prepare query
|
||||
int set_nvidia_query(struct text_object *obj, const char *arg,
|
||||
unsigned int special_type) {
|
||||
text_node_t special_type) {
|
||||
nvidia_s *nvs;
|
||||
int aid;
|
||||
int ilen;
|
||||
@@ -451,15 +453,15 @@ int set_nvidia_query(struct text_object *obj, const char *arg,
|
||||
|
||||
// Extract arguments for nvidiabar, etc, and run set_nvidia_query
|
||||
switch (special_type) {
|
||||
case BAR:
|
||||
case text_node_t::BAR:
|
||||
arg = scan_bar(obj, arg, 100);
|
||||
break;
|
||||
case GRAPH: {
|
||||
case text_node_t::GRAPH: {
|
||||
auto [buf, skip] = scan_command(arg);
|
||||
scan_graph(obj, arg + skip, 100);
|
||||
arg = buf;
|
||||
} break;
|
||||
case GAUGE:
|
||||
case text_node_t::GAUGE:
|
||||
arg = scan_gauge(obj, arg, 100);
|
||||
break;
|
||||
default:
|
||||
@@ -483,7 +485,7 @@ int set_nvidia_query(struct text_object *obj, const char *arg,
|
||||
|
||||
// Save pointers to the arg and command strings for debugging and printing
|
||||
nvs->arg = translate_module_argument[aid];
|
||||
nvs->command = translate_nvidia_special_type[special_type];
|
||||
nvs->command = translate_nvidia_special_type[*special_type];
|
||||
|
||||
// Evaluate parameter
|
||||
switch (aid) {
|
||||
|
@@ -30,7 +30,9 @@
|
||||
#ifndef NVIDIA_CONKY_H
|
||||
#define NVIDIA_CONKY_H
|
||||
|
||||
int set_nvidia_query(struct text_object *, const char *, unsigned int);
|
||||
#include "specials.h"
|
||||
|
||||
int set_nvidia_query(struct text_object *, const char *, text_node_t);
|
||||
void print_nvidia_value(struct text_object *, char *, unsigned int);
|
||||
double get_nvidia_barval(struct text_object *);
|
||||
void free_nvidia(struct text_object *);
|
||||
|
@@ -323,7 +323,8 @@ void print_scroll(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
#ifdef BUILD_GUI
|
||||
// reset color when scroll is finished
|
||||
if (display_output() && display_output()->graphical()) {
|
||||
new_special(p + strlen(p), FG)->arg = sd->resetcolor.to_argb32();
|
||||
new_special(p + strlen(p), text_node_t::FG)->arg =
|
||||
sd->resetcolor.to_argb32();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -46,7 +46,7 @@
|
||||
#include "conky.h"
|
||||
#include "display-output.hh"
|
||||
|
||||
struct special_t *specials = nullptr;
|
||||
struct special_node *specials = nullptr;
|
||||
|
||||
int special_count;
|
||||
int graph_count = 0;
|
||||
@@ -354,8 +354,8 @@ bool scan_graph(struct text_object *obj, const char *argstr, double defscale) {
|
||||
* Printing various special text objects
|
||||
*/
|
||||
|
||||
struct special_t *new_special_t_node() {
|
||||
auto *newnode = new special_t;
|
||||
struct special_node *new_special_t_node() {
|
||||
auto *newnode = new special_node;
|
||||
|
||||
memset(newnode, 0, sizeof *newnode);
|
||||
return newnode;
|
||||
@@ -369,8 +369,8 @@ struct special_t *new_special_t_node() {
|
||||
* @param[in] t special type enum, e.g. alignc, alignr, fg, bg, ...
|
||||
* @return pointer to the newly inserted special of type t
|
||||
**/
|
||||
struct special_t *new_special(char *buf, enum special_types t) {
|
||||
special_t *current;
|
||||
struct special_node *new_special(char *buf, text_node_t t) {
|
||||
special_node *current;
|
||||
|
||||
buf[0] = SPECIAL_CHAR;
|
||||
buf[1] = '\0';
|
||||
@@ -397,14 +397,14 @@ void new_gauge_in_shell(struct text_object *obj, char *p,
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
void new_gauge_in_gui(struct text_object *obj, char *buf, double usage) {
|
||||
struct special_t *s = nullptr;
|
||||
struct special_node *s = nullptr;
|
||||
auto *g = static_cast<struct gauge *>(obj->special_data);
|
||||
|
||||
if (display_output() == nullptr || !display_output()->graphical()) { return; }
|
||||
|
||||
if (g == nullptr) { return; }
|
||||
|
||||
s = new_special(buf, GAUGE);
|
||||
s = new_special(buf, text_node_t::GAUGE);
|
||||
|
||||
s->arg = usage;
|
||||
s->width = dpi_scale(g->width);
|
||||
@@ -439,14 +439,14 @@ void new_gauge(struct text_object *obj, char *p, unsigned int p_max_size,
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
void new_font(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
struct special_t *s;
|
||||
struct special_node *s;
|
||||
unsigned int tmp = selected_font;
|
||||
|
||||
if (display_output() == nullptr || !display_output()->graphical()) { return; }
|
||||
|
||||
if (p_max_size == 0) { return; }
|
||||
|
||||
s = new_special(p, FONT);
|
||||
s = new_special(p, text_node_t::FONT);
|
||||
|
||||
if (obj->data.s != nullptr) {
|
||||
if (s->font_added >= static_cast<int>(fonts.size()) ||
|
||||
@@ -463,7 +463,7 @@ void new_font(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
/**
|
||||
* Adds value f to graph possibly truncating and scaling the graph
|
||||
**/
|
||||
static void graph_append(struct special_t *graph, double f, char showaslog) {
|
||||
static void graph_append(struct special_node *graph, double f, char showaslog) {
|
||||
int i;
|
||||
|
||||
/* do nothing if we don't even have a graph yet */
|
||||
@@ -494,7 +494,7 @@ static void graph_append(struct special_t *graph, double f, char showaslog) {
|
||||
}
|
||||
}
|
||||
|
||||
void new_graph_in_shell(struct special_t *s, char *buf, int buf_max_size) {
|
||||
void new_graph_in_shell(struct special_node *s, char *buf, int buf_max_size) {
|
||||
// Split config string on comma to avoid the hassle of dealing with the
|
||||
// idiosyncrasies of multi-byte unicode on different platforms.
|
||||
// TODO(brenden): Parse config string once and cache result.
|
||||
@@ -537,7 +537,7 @@ double *retrieve_graph(int graph_id, int graph_width) {
|
||||
}
|
||||
}
|
||||
|
||||
void store_graph(int graph_id, struct special_t *s) {
|
||||
void store_graph(int graph_id, struct special_node *s) {
|
||||
if (s->graph == nullptr) {
|
||||
graphs[graph_id] = nullptr;
|
||||
} else {
|
||||
@@ -556,12 +556,12 @@ void store_graph(int graph_id, struct special_t *s) {
|
||||
**/
|
||||
void new_graph(struct text_object *obj, char *buf, int buf_max_size,
|
||||
double val) {
|
||||
struct special_t *s = nullptr;
|
||||
struct special_node *s = nullptr;
|
||||
auto *g = static_cast<struct graph *>(obj->special_data);
|
||||
|
||||
if ((g == nullptr) || (buf_max_size == 0)) { return; }
|
||||
|
||||
s = new_special(buf, GRAPH);
|
||||
s = new_special(buf, text_node_t::GRAPH);
|
||||
|
||||
/* set graph (special) width to width in obj */
|
||||
s->width = dpi_scale(g->width);
|
||||
@@ -628,7 +628,7 @@ void new_hr(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
|
||||
if (p_max_size == 0) { return; }
|
||||
|
||||
new_special(p, HORIZONTAL_LINE)->height = dpi_scale(obj->data.l);
|
||||
new_special(p, text_node_t::HORIZONTAL_LINE)->height = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void scan_stippled_hr(struct text_object *obj, const char *arg) {
|
||||
@@ -651,14 +651,14 @@ void scan_stippled_hr(struct text_object *obj, const char *arg) {
|
||||
|
||||
void new_stippled_hr(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
struct special_t *s = nullptr;
|
||||
struct special_node *s = nullptr;
|
||||
auto *sh = static_cast<struct stippled_hr *>(obj->special_data);
|
||||
|
||||
if (display_output() == nullptr || !display_output()->graphical()) { return; }
|
||||
|
||||
if ((sh == nullptr) || (p_max_size == 0)) { return; }
|
||||
|
||||
s = new_special(p, STIPPLED_HR);
|
||||
s = new_special(p, text_node_t::STIPPLED_HR);
|
||||
|
||||
s->height = dpi_scale(sh->height);
|
||||
s->arg = dpi_scale(sh->arg);
|
||||
@@ -674,7 +674,7 @@ void new_fg(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
|| out_to_ncurses.get(*state)
|
||||
#endif /* BUILD_NCURSES */
|
||||
) {
|
||||
new_special(p, FG)->arg = obj->data.l;
|
||||
new_special(p, text_node_t::FG)->arg = obj->data.l;
|
||||
}
|
||||
UNUSED(obj);
|
||||
UNUSED(p);
|
||||
@@ -687,7 +687,7 @@ void new_bg(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
|
||||
if (p_max_size == 0) { return; }
|
||||
|
||||
new_special(p, BG)->arg = obj->data.l;
|
||||
new_special(p, text_node_t::BG)->arg = obj->data.l;
|
||||
}
|
||||
#endif /* BUILD_GUI */
|
||||
|
||||
@@ -716,14 +716,14 @@ static void new_bar_in_shell(struct text_object *obj, char *buffer,
|
||||
|
||||
#ifdef BUILD_GUI
|
||||
static void new_bar_in_gui(struct text_object *obj, char *buf, double usage) {
|
||||
struct special_t *s = nullptr;
|
||||
struct special_node *s = nullptr;
|
||||
auto *b = static_cast<struct bar *>(obj->special_data);
|
||||
|
||||
if (display_output() == nullptr || !display_output()->graphical()) { return; }
|
||||
|
||||
if (b == nullptr) { return; }
|
||||
|
||||
s = new_special(buf, BAR);
|
||||
s = new_special(buf, text_node_t::BAR);
|
||||
|
||||
s->arg = usage;
|
||||
s->width = dpi_scale(b->width);
|
||||
@@ -759,39 +759,39 @@ void new_bar(struct text_object *obj, char *p, unsigned int p_max_size,
|
||||
|
||||
void new_outline(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, OUTLINE)->arg = obj->data.l;
|
||||
new_special(p, text_node_t::OUTLINE)->arg = obj->data.l;
|
||||
}
|
||||
|
||||
void new_offset(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, OFFSET)->arg = dpi_scale(obj->data.l);
|
||||
new_special(p, text_node_t::OFFSET)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void new_voffset(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, VOFFSET)->arg = dpi_scale(obj->data.l);
|
||||
new_special(p, text_node_t::VOFFSET)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void new_save_coordinates(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, SAVE_COORDINATES)->arg = obj->data.l;
|
||||
new_special(p, text_node_t::SAVE_COORDINATES)->arg = obj->data.l;
|
||||
}
|
||||
|
||||
void new_alignr(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, ALIGNR)->arg = dpi_scale(obj->data.l);
|
||||
new_special(p, text_node_t::ALIGNR)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
// A positive offset pushes the text further left
|
||||
void new_alignc(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, ALIGNC)->arg = dpi_scale(obj->data.l);
|
||||
new_special(p, text_node_t::ALIGNC)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void new_goto(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
if (p_max_size == 0) { return; }
|
||||
new_special(p, GOTO)->arg = dpi_scale(obj->data.l);
|
||||
new_special(p, text_node_t::GOTO)->arg = dpi_scale(obj->data.l);
|
||||
}
|
||||
|
||||
void scan_tab(struct text_object *obj, const char *arg) {
|
||||
@@ -813,12 +813,12 @@ void scan_tab(struct text_object *obj, const char *arg) {
|
||||
}
|
||||
|
||||
void new_tab(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
struct special_t *s = nullptr;
|
||||
struct special_node *s = nullptr;
|
||||
auto *t = static_cast<struct tab *>(obj->special_data);
|
||||
|
||||
if ((t == nullptr) || (p_max_size == 0)) { return; }
|
||||
|
||||
s = new_special(p, TAB);
|
||||
s = new_special(p, text_node_t::TAB);
|
||||
s->width = dpi_scale(t->width);
|
||||
s->arg = dpi_scale(t->arg);
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@
|
||||
#define LOGGRAPH "-l"
|
||||
#define TEMPGRAD "-t"
|
||||
|
||||
enum special_types {
|
||||
enum class text_node_t : uint32_t {
|
||||
NONSPECIAL = 0,
|
||||
HORIZONTAL_LINE = 1,
|
||||
STIPPLED_HR,
|
||||
@@ -59,9 +59,12 @@ enum special_types {
|
||||
GOTO,
|
||||
TAB
|
||||
};
|
||||
constexpr uint32_t operator*(text_node_t index) {
|
||||
return static_cast<uint32_t>(index);
|
||||
}
|
||||
|
||||
struct special_t {
|
||||
int type;
|
||||
struct special_node {
|
||||
text_node_t type;
|
||||
short height;
|
||||
short width;
|
||||
double arg;
|
||||
@@ -77,11 +80,11 @@ struct special_t {
|
||||
Colour last_colour;
|
||||
short font_added;
|
||||
char tempgrad;
|
||||
struct special_t *next;
|
||||
struct special_node *next;
|
||||
};
|
||||
|
||||
/* direct access to the registered specials (FIXME: bad encapsulation) */
|
||||
extern struct special_t *specials;
|
||||
extern struct special_node *specials;
|
||||
extern int special_count;
|
||||
|
||||
/* forward declare to avoid mutual inclusion between specials.h and
|
||||
@@ -119,6 +122,6 @@ void new_tab(struct text_object *, char *, unsigned int);
|
||||
|
||||
void clear_stored_graphs();
|
||||
|
||||
struct special_t *new_special(char *buf, enum special_types t);
|
||||
struct special_node *new_special(char *buf, enum text_node_t t);
|
||||
|
||||
#endif /* _SPECIALS_H */
|
||||
|
@@ -29,11 +29,19 @@
|
||||
#ifndef _TEXT_OBJECT_H
|
||||
#define _TEXT_OBJECT_H
|
||||
|
||||
#include <stdint.h> /* uint8_t */
|
||||
#include "config.h" /* for the defines */
|
||||
#include "config.h"
|
||||
|
||||
#include "exec.h"
|
||||
#include "specials.h" /* enum special_types */
|
||||
|
||||
#include <cstdint> /* uint8_t */
|
||||
|
||||
enum class draw_mode_t : uint32_t {
|
||||
BG = static_cast<uint32_t>(text_node_t::BG),
|
||||
FG = static_cast<uint32_t>(text_node_t::FG),
|
||||
OUTLINE = static_cast<uint32_t>(text_node_t::OUTLINE),
|
||||
};
|
||||
|
||||
/* text object callbacks */
|
||||
struct obj_cb {
|
||||
/* text object: print obj's output to p */
|
||||
|
8
src/wl.h
8
src/wl.h
@@ -27,9 +27,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(BUILD_WAYLAND) && !defined(CONKY_WL_H)
|
||||
#ifndef CONKY_WL_H
|
||||
#define CONKY_WL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef BUILD_WAYLAND
|
||||
#error wl.h included when BUILD_WAYLAND is disabled
|
||||
#endif
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "setting.hh"
|
||||
|
@@ -1566,15 +1566,12 @@ static const BuiltinColor BuiltinColors[] = {
|
||||
|
||||
#define NUM_BUILTIN_COLORS (sizeof(BuiltinColors) / sizeof(BuiltinColors[0]))
|
||||
|
||||
int OsLookupColor(int screen, const char *name, unsigned int len,
|
||||
unsigned short *pred, unsigned short *pgreen,
|
||||
unsigned short *pblue) {
|
||||
int OsLookupColor(const char *name, unsigned int len, unsigned short *pred,
|
||||
unsigned short *pgreen, unsigned short *pblue) {
|
||||
const BuiltinColor *c;
|
||||
int low, mid, high;
|
||||
int r;
|
||||
|
||||
(void)screen;
|
||||
|
||||
low = 0;
|
||||
high = NUM_BUILTIN_COLORS - 1;
|
||||
while (high >= low) {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
/* from xorg-server's oscolor.c */
|
||||
int OsLookupColor(int screen, const char *name, unsigned int len,
|
||||
unsigned short *pred, unsigned short *pgreen,
|
||||
unsigned short *pblue);
|
||||
int OsLookupColor(const char *name, unsigned int len, unsigned short *pred,
|
||||
unsigned short *pgreen, unsigned short *pblue);
|
126
src/x11-settings.cc
Normal file
126
src/x11-settings.cc
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "x11-settings.h"
|
||||
|
||||
#include "x11.h"
|
||||
|
||||
#include "conky-imlib2.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
conky::simple_config_setting<std::string> display_name("display", std::string(),
|
||||
false);
|
||||
|
||||
namespace priv {
|
||||
void out_to_x_setting::lua_setter(lua::state &l, bool init) {
|
||||
lua::stack_sentry s(l, -2);
|
||||
|
||||
Base::lua_setter(l, init);
|
||||
|
||||
if (init && do_convert(l, -1).first) { init_x11(); }
|
||||
|
||||
++s;
|
||||
}
|
||||
|
||||
void out_to_x_setting::cleanup(lua::state &l) {
|
||||
lua::stack_sentry s(l, -1);
|
||||
|
||||
if (do_convert(l, -1).first) { deinit_x11(); }
|
||||
|
||||
l.pop();
|
||||
}
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
bool use_xdbe_setting::set_up(lua::state &l) {
|
||||
// double_buffer makes no sense when not drawing to X
|
||||
if (!out_to_x.get(l) || !display || !window.window) { return false; }
|
||||
|
||||
int major, minor;
|
||||
|
||||
if (XdbeQueryExtension(display, &major, &minor) == 0) {
|
||||
NORM_ERR("No compatible double buffer extension found");
|
||||
return false;
|
||||
}
|
||||
|
||||
window.back_buffer =
|
||||
XdbeAllocateBackBufferName(display, window.window, XdbeBackground);
|
||||
if (window.back_buffer != None) {
|
||||
window.drawable = window.back_buffer;
|
||||
} else {
|
||||
NORM_ERR("Failed to allocate back buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
XFlush(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
void use_xdbe_setting::lua_setter(lua::state &l, bool init) {
|
||||
lua::stack_sentry s(l, -2);
|
||||
|
||||
Base::lua_setter(l, init);
|
||||
|
||||
if (init && do_convert(l, -1).first) {
|
||||
if (!set_up(l)) {
|
||||
l.pop();
|
||||
l.pushboolean(false);
|
||||
}
|
||||
|
||||
NORM_ERR("drawing to %s buffer",
|
||||
do_convert(l, -1).first ? "double" : "single");
|
||||
}
|
||||
|
||||
++s;
|
||||
}
|
||||
|
||||
#else
|
||||
bool use_xpmdb_setting::set_up(lua::state &l) {
|
||||
// double_buffer makes no sense when not drawing to X
|
||||
if (!out_to_x.get(l)) return false;
|
||||
|
||||
window.back_buffer =
|
||||
XCreatePixmap(display, window.window, window.width + 1, window.height + 1,
|
||||
DefaultDepth(display, screen));
|
||||
if (window.back_buffer != None) {
|
||||
window.drawable = window.back_buffer;
|
||||
} else {
|
||||
NORM_ERR("Failed to allocate back buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
XFlush(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
void use_xpmdb_setting::lua_setter(lua::state &l, bool init) {
|
||||
lua::stack_sentry s(l, -2);
|
||||
|
||||
Base::lua_setter(l, init);
|
||||
|
||||
if (init && do_convert(l, -1).first) {
|
||||
if (!set_up(l)) {
|
||||
l.pop();
|
||||
l.pushboolean(false);
|
||||
}
|
||||
|
||||
NORM_ERR("drawing to %s buffer",
|
||||
do_convert(l, -1).first ? "double" : "single");
|
||||
}
|
||||
|
||||
++s;
|
||||
}
|
||||
#endif
|
||||
} // namespace priv
|
||||
|
||||
conky::simple_config_setting<int> head_index("xinerama_head", 0, true);
|
||||
priv::out_to_x_setting out_to_x;
|
||||
|
||||
#ifdef BUILD_XFT
|
||||
conky::simple_config_setting<bool> use_xft("use_xft", false, false);
|
||||
#endif
|
||||
|
||||
conky::simple_config_setting<bool> forced_redraw("forced_redraw", false, false);
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
priv::use_xdbe_setting use_xdbe;
|
||||
#else
|
||||
priv::use_xpmdb_setting use_xpmdb;
|
||||
#endif
|
60
src/x11-settings.h
Normal file
60
src/x11-settings.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef CONKY_X11_SETTINGS_H
|
||||
#define CONKY_X11_SETTINGS_H
|
||||
|
||||
#include "setting.hh"
|
||||
|
||||
extern conky::simple_config_setting<std::string> display_name;
|
||||
|
||||
namespace priv {
|
||||
class out_to_x_setting : public conky::simple_config_setting<bool> {
|
||||
typedef conky::simple_config_setting<bool> Base;
|
||||
|
||||
protected:
|
||||
virtual void lua_setter(lua::state &l, bool init);
|
||||
virtual void cleanup(lua::state &l);
|
||||
|
||||
public:
|
||||
out_to_x_setting() : Base("out_to_x", true, false) {}
|
||||
};
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
class use_xdbe_setting : public conky::simple_config_setting<bool> {
|
||||
typedef conky::simple_config_setting<bool> Base;
|
||||
|
||||
bool set_up(lua::state &l);
|
||||
|
||||
protected:
|
||||
virtual void lua_setter(lua::state &l, bool init);
|
||||
|
||||
public:
|
||||
use_xdbe_setting() : Base("double_buffer", false, false) {}
|
||||
};
|
||||
|
||||
#else
|
||||
class use_xpmdb_setting : public conky::simple_config_setting<bool> {
|
||||
typedef conky::simple_config_setting<bool> Base;
|
||||
|
||||
bool set_up(lua::state &l);
|
||||
|
||||
protected:
|
||||
virtual void lua_setter(lua::state &l, bool init);
|
||||
|
||||
public:
|
||||
use_xpmdb_setting() : Base("double_buffer", false, false) {}
|
||||
};
|
||||
#endif
|
||||
} /* namespace priv */
|
||||
|
||||
extern priv::out_to_x_setting out_to_x;
|
||||
|
||||
#ifdef BUILD_XFT
|
||||
extern conky::simple_config_setting<bool> use_xft;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
extern priv::use_xdbe_setting use_xdbe;
|
||||
#else
|
||||
extern priv::use_xpmdb_setting use_xpmdb;
|
||||
#endif
|
||||
|
||||
#endif /* CONKY_X11_SETTINGS_H */
|
228
src/x11.cc
228
src/x11.cc
@@ -43,13 +43,19 @@
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
|
||||
// #ifndef OWN_WINDOW
|
||||
// #include <iostream>
|
||||
// #endif
|
||||
|
||||
extern "C" {
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
@@ -64,9 +70,6 @@ extern "C" {
|
||||
#ifdef BUILD_IMLIB2
|
||||
#include "conky-imlib2.h"
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#ifndef OWN_WINDOW
|
||||
#include <iostream>
|
||||
#endif
|
||||
#ifdef BUILD_XFT
|
||||
#include <X11/Xft/Xft.h>
|
||||
#endif
|
||||
@@ -100,144 +103,12 @@ xcb_errors_context_t *xcb_errors_ctx;
|
||||
/* Window stuff */
|
||||
struct conky_x11_window window;
|
||||
|
||||
#ifdef BUILD_ARGB
|
||||
bool have_argb_visual;
|
||||
#endif /* BUILD_ARGB */
|
||||
|
||||
conky::simple_config_setting<std::string> display_name("display", std::string(),
|
||||
false);
|
||||
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 void init_x11();
|
||||
|
||||
/********************* <SETTINGS> ************************/
|
||||
namespace priv {
|
||||
void out_to_x_setting::lua_setter(lua::state &l, bool init) {
|
||||
lua::stack_sentry s(l, -2);
|
||||
|
||||
Base::lua_setter(l, init);
|
||||
|
||||
if (init && do_convert(l, -1).first) { init_x11(); }
|
||||
|
||||
++s;
|
||||
}
|
||||
|
||||
void out_to_x_setting::cleanup(lua::state &l) {
|
||||
lua::stack_sentry s(l, -1);
|
||||
|
||||
if (do_convert(l, -1).first) { deinit_x11(); }
|
||||
|
||||
l.pop();
|
||||
}
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
bool use_xdbe_setting::set_up(lua::state &l) {
|
||||
// double_buffer makes no sense when not drawing to X
|
||||
if (!out_to_x.get(l) || !display || !window.window) { return false; }
|
||||
|
||||
int major, minor;
|
||||
|
||||
if (XdbeQueryExtension(display, &major, &minor) == 0) {
|
||||
NORM_ERR("No compatible double buffer extension found");
|
||||
return false;
|
||||
}
|
||||
|
||||
window.back_buffer =
|
||||
XdbeAllocateBackBufferName(display, window.window, XdbeBackground);
|
||||
if (window.back_buffer != None) {
|
||||
window.drawable = window.back_buffer;
|
||||
} else {
|
||||
NORM_ERR("Failed to allocate back buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
XFlush(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
void use_xdbe_setting::lua_setter(lua::state &l, bool init) {
|
||||
lua::stack_sentry s(l, -2);
|
||||
|
||||
Base::lua_setter(l, init);
|
||||
|
||||
if (init && do_convert(l, -1).first) {
|
||||
if (!set_up(l)) {
|
||||
l.pop();
|
||||
l.pushboolean(false);
|
||||
}
|
||||
|
||||
NORM_ERR("drawing to %s buffer",
|
||||
do_convert(l, -1).first ? "double" : "single");
|
||||
}
|
||||
|
||||
++s;
|
||||
}
|
||||
|
||||
#else
|
||||
bool use_xpmdb_setting::set_up(lua::state &l) {
|
||||
// double_buffer makes no sense when not drawing to X
|
||||
if (!out_to_x.get(l)) return false;
|
||||
|
||||
window.back_buffer =
|
||||
XCreatePixmap(display, window.window, window.width + 1, window.height + 1,
|
||||
DefaultDepth(display, screen));
|
||||
if (window.back_buffer != None) {
|
||||
window.drawable = window.back_buffer;
|
||||
} else {
|
||||
NORM_ERR("Failed to allocate back buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
XFlush(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
void use_xpmdb_setting::lua_setter(lua::state &l, bool init) {
|
||||
lua::stack_sentry s(l, -2);
|
||||
|
||||
Base::lua_setter(l, init);
|
||||
|
||||
if (init && do_convert(l, -1).first) {
|
||||
if (!set_up(l)) {
|
||||
l.pop();
|
||||
l.pushboolean(false);
|
||||
}
|
||||
|
||||
NORM_ERR("drawing to %s buffer",
|
||||
do_convert(l, -1).first ? "double" : "single");
|
||||
}
|
||||
|
||||
++s;
|
||||
}
|
||||
#endif
|
||||
} // namespace priv
|
||||
|
||||
conky::simple_config_setting<int> head_index("xinerama_head", 0, true);
|
||||
priv::out_to_x_setting out_to_x;
|
||||
|
||||
#ifdef BUILD_XFT
|
||||
conky::simple_config_setting<bool> use_xft("use_xft", false, false);
|
||||
#endif
|
||||
|
||||
conky::simple_config_setting<bool> forced_redraw("forced_redraw", false, false);
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
priv::use_xdbe_setting use_xdbe;
|
||||
#else
|
||||
priv::use_xpmdb_setting use_xpmdb;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_IMLIB2
|
||||
/*
|
||||
* the only reason this is not in imlib2.cc is so that we can be sure it's
|
||||
* setter executes after use_xdbe
|
||||
*/
|
||||
imlib_cache_size_setting imlib_cache_size;
|
||||
#endif
|
||||
/******************** </SETTINGS> ************************/
|
||||
|
||||
/* WARNING, this type not in Xlib spec */
|
||||
static int x11_error_handler(Display *d, XErrorEvent *err) {
|
||||
@@ -362,7 +233,7 @@ inline Window DefaultVRootWindow(Display *display) {
|
||||
}
|
||||
|
||||
/* X11 initializer */
|
||||
static void init_x11() {
|
||||
void init_x11() {
|
||||
DBGP("enter init_x11()");
|
||||
if (display == nullptr) {
|
||||
const std::string &dispstr = display_name.get(*state);
|
||||
@@ -494,7 +365,8 @@ namespace {
|
||||
void do_set_background(Window win, uint8_t alpha) {
|
||||
Colour colour = background_colour.get(*state);
|
||||
colour.alpha = alpha;
|
||||
unsigned long xcolor = colour.to_x11_color(display, screen, true);
|
||||
unsigned long xcolor =
|
||||
colour.to_x11_color(display, screen, have_argb_visual, true);
|
||||
XSetWindowBackground(display, win, xcolor);
|
||||
}
|
||||
} // namespace
|
||||
@@ -624,7 +496,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
classHint.res_name = const_cast<char *>(class_name.c_str());
|
||||
classHint.res_class = classHint.res_name;
|
||||
|
||||
if (own_window_type.get(l) == TYPE_OVERRIDE) {
|
||||
if (own_window_type.get(l) == window_type::OVERRIDE) {
|
||||
/* An override_redirect True window.
|
||||
* No WM hints or button processing needed. */
|
||||
XSetWindowAttributes attrs = {ParentRelative,
|
||||
@@ -678,7 +550,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
StructureNotifyMask | ExposureMask | ButtonPressMask |
|
||||
ButtonReleaseMask,
|
||||
0L,
|
||||
own_window_type.get(l) == TYPE_UTILITY ? True : False,
|
||||
own_window_type.get(l) == window_type::UTILITY ? True : False,
|
||||
0,
|
||||
0};
|
||||
|
||||
@@ -694,7 +566,9 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
|
||||
if (own_window_type.get(l) == TYPE_DOCK) { window.x = window.y = 0; }
|
||||
if (own_window_type.get(l) == window_type::DOCK) {
|
||||
window.x = window.y = 0;
|
||||
}
|
||||
/* Parent is root window so WM can take control */
|
||||
window.window =
|
||||
XCreateWindow(display, window.root, window.x, window.y, b, b, 0,
|
||||
@@ -704,10 +578,10 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
|
||||
wmHint.flags = InputHint | StateHint;
|
||||
/* allow decorated windows to be given input focus by WM */
|
||||
wmHint.input = TEST_HINT(hints, HINT_UNDECORATED) ? False : True;
|
||||
wmHint.input = TEST_HINT(hints, window_hints::UNDECORATED) ? False : True;
|
||||
#ifdef BUILD_XSHAPE
|
||||
#ifdef BUILD_XFIXES
|
||||
if (own_window_type.get(l) == TYPE_UTILITY) {
|
||||
if (own_window_type.get(l) == window_type::UTILITY) {
|
||||
XRectangle rect;
|
||||
XserverRegion region = XFixesCreateRegion(display, &rect, 1);
|
||||
XFixesSetWindowShapeRegion(display, window.window, ShapeInput, 0, 0,
|
||||
@@ -723,18 +597,18 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
NORM_ERR("Input shapes are not supported");
|
||||
} else {
|
||||
if (own_window.get(*state) &&
|
||||
(own_window_type.get(*state) != TYPE_NORMAL ||
|
||||
((TEST_HINT(own_window_hints.get(*state), HINT_UNDECORATED)) !=
|
||||
0))) {
|
||||
(own_window_type.get(*state) != window_type::NORMAL ||
|
||||
((TEST_HINT(own_window_hints.get(*state),
|
||||
window_hints::UNDECORATED)) != 0))) {
|
||||
XShapeCombineRectangles(display, window.window, ShapeInput, 0, 0,
|
||||
nullptr, 0, ShapeSet, Unsorted);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* BUILD_XSHAPE */
|
||||
if (own_window_type.get(l) == TYPE_DOCK ||
|
||||
own_window_type.get(l) == TYPE_PANEL) {
|
||||
wmHint.initial_state = WithdrawnState;
|
||||
if (own_window_type.get(l) == window_type::DOCK ||
|
||||
own_window_type.get(l) == window_type::PANEL) {
|
||||
// wmHint.initial_state = WithdrawnState;
|
||||
} else {
|
||||
wmHint.initial_state = NormalState;
|
||||
}
|
||||
@@ -751,23 +625,23 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
Atom prop;
|
||||
|
||||
switch (own_window_type.get(l)) {
|
||||
case TYPE_DESKTOP:
|
||||
case window_type::DESKTOP:
|
||||
prop = ATOM(_NET_WM_WINDOW_TYPE_DESKTOP);
|
||||
NORM_ERR("window type - desktop");
|
||||
break;
|
||||
case TYPE_DOCK:
|
||||
case window_type::DOCK:
|
||||
prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK);
|
||||
NORM_ERR("window type - dock");
|
||||
break;
|
||||
case TYPE_PANEL:
|
||||
case window_type::PANEL:
|
||||
prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK);
|
||||
NORM_ERR("window type - panel");
|
||||
break;
|
||||
case TYPE_UTILITY:
|
||||
case window_type::UTILITY:
|
||||
prop = ATOM(_NET_WM_WINDOW_TYPE_UTILITY);
|
||||
NORM_ERR("window type - utility");
|
||||
break;
|
||||
case TYPE_NORMAL:
|
||||
case window_type::NORMAL:
|
||||
default:
|
||||
prop = ATOM(_NET_WM_WINDOW_TYPE_NORMAL);
|
||||
NORM_ERR("window type - normal");
|
||||
@@ -781,7 +655,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
/* Set desired hints */
|
||||
|
||||
/* Window decorations */
|
||||
if (TEST_HINT(hints, HINT_UNDECORATED)) {
|
||||
if (TEST_HINT(hints, window_hints::UNDECORATED)) {
|
||||
DBGP("hint - undecorated");
|
||||
xa = ATOM(_MOTIF_WM_HINTS);
|
||||
if (xa != None) {
|
||||
@@ -792,7 +666,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
}
|
||||
|
||||
/* Below other windows */
|
||||
if (TEST_HINT(hints, HINT_BELOW)) {
|
||||
if (TEST_HINT(hints, window_hints::BELOW)) {
|
||||
DBGP("hint - below");
|
||||
xa = ATOM(_WIN_LAYER);
|
||||
if (xa != None) {
|
||||
@@ -814,7 +688,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
}
|
||||
|
||||
/* Above other windows */
|
||||
if (TEST_HINT(hints, HINT_ABOVE)) {
|
||||
if (TEST_HINT(hints, window_hints::ABOVE)) {
|
||||
DBGP("hint - above");
|
||||
xa = ATOM(_WIN_LAYER);
|
||||
if (xa != None) {
|
||||
@@ -836,7 +710,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
}
|
||||
|
||||
/* Sticky */
|
||||
if (TEST_HINT(hints, HINT_STICKY)) {
|
||||
if (TEST_HINT(hints, window_hints::STICKY)) {
|
||||
DBGP("hint - sticky");
|
||||
xa = ATOM(_NET_WM_DESKTOP);
|
||||
if (xa != None) {
|
||||
@@ -858,7 +732,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
}
|
||||
|
||||
/* Skip taskbar */
|
||||
if (TEST_HINT(hints, HINT_SKIP_TASKBAR)) {
|
||||
if (TEST_HINT(hints, window_hints::SKIP_TASKBAR)) {
|
||||
DBGP("hint - skip taskbar");
|
||||
xa = ATOM(_NET_WM_STATE);
|
||||
if (xa != None) {
|
||||
@@ -871,7 +745,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
}
|
||||
|
||||
/* Skip pager */
|
||||
if (TEST_HINT(hints, HINT_SKIP_PAGER)) {
|
||||
if (TEST_HINT(hints, window_hints::SKIP_PAGER)) {
|
||||
DBGP("hint - skip pager");
|
||||
xa = ATOM(_NET_WM_STATE);
|
||||
if (xa != None) {
|
||||
@@ -909,9 +783,12 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
int64_t input_mask = ExposureMask | PropertyChangeMask;
|
||||
#ifdef OWN_WINDOW
|
||||
if (own_window.get(l)) {
|
||||
input_mask |= StructureNotifyMask | ButtonPressMask | ButtonReleaseMask;
|
||||
input_mask |= StructureNotifyMask;
|
||||
#if !defined(BUILD_XINPUT)
|
||||
input_mask |= ButtonPressMask | ButtonReleaseMask;
|
||||
#endif
|
||||
}
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
#if defined(BUILD_MOUSE_EVENTS) || defined(BUILD_XINPUT)
|
||||
bool xinput_ok = false;
|
||||
#ifdef BUILD_XINPUT
|
||||
// not a loop; substitutes goto with break - if checks fail
|
||||
@@ -934,7 +811,9 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
const std::size_t mask_size = (XI_LASTEVENT + 7) / 8;
|
||||
unsigned char mask_bytes[mask_size] = {0}; /* must be zeroed! */
|
||||
XISetMask(mask_bytes, XI_HierarchyChanged);
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
XISetMask(mask_bytes, XI_Motion);
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
// Capture click events for "override" window type
|
||||
if (!own) {
|
||||
XISetMask(mask_bytes, XI_ButtonPress);
|
||||
@@ -948,7 +827,9 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
XISelectEvents(display, window.root, ev_masks, 1);
|
||||
|
||||
if (own) {
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
XIClearMask(mask_bytes, XI_Motion);
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
XISetMask(mask_bytes, XI_ButtonPress);
|
||||
XISetMask(mask_bytes, XI_ButtonRelease);
|
||||
|
||||
@@ -974,10 +855,12 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
// Fallback to basic X11 enter/leave events if xinput fails to init.
|
||||
// It's not recommended to add event masks to special windows in X; causes a
|
||||
// crash (thus own_window_type != TYPE_DESKTOP)
|
||||
if (!xinput_ok && own && own_window_type.get(l) != TYPE_DESKTOP) {
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
if (!xinput_ok && own && own_window_type.get(l) != window_type::DESKTOP) {
|
||||
input_mask |= PointerMotionMask | EnterWindowMask | LeaveWindowMask;
|
||||
}
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_MOUSE_EVENTS || BUILD_XINPUT */
|
||||
#endif /* OWN_WINDOW */
|
||||
window.event_mask = input_mask;
|
||||
XSelectInput(display, window.window, input_mask);
|
||||
@@ -1205,6 +1088,25 @@ void print_desktop_name(struct text_object *obj, char *p,
|
||||
}
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
enum class x11_strut : size_t {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
TOP,
|
||||
BOTTOM,
|
||||
LEFT_START_Y,
|
||||
LEFT_END_Y,
|
||||
RIGHT_START_Y,
|
||||
RIGHT_END_Y,
|
||||
TOP_START_X,
|
||||
TOP_END_X,
|
||||
BOTTOM_START_X,
|
||||
BOTTOM_END_X,
|
||||
};
|
||||
const size_t STRUT_COUNT = static_cast<size_t>(x11_strut::BOTTOM_END_X) + 1;
|
||||
constexpr size_t operator*(x11_strut index) {
|
||||
return static_cast<size_t>(index);
|
||||
}
|
||||
|
||||
/* reserve window manager space */
|
||||
void set_struts(int sidenum) {
|
||||
Atom strut;
|
||||
|
96
src/x11.h
96
src/x11.h
@@ -22,10 +22,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef CONKY_X11_H
|
||||
#define CONKY_X11_H
|
||||
|
||||
#include "config.h"
|
||||
#include "setting.hh"
|
||||
|
||||
#ifndef BUILD_X11
|
||||
#error x11.h included when BUILD_X11 is disabled
|
||||
#endif
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#pragma GCC diagnostic push
|
||||
@@ -44,36 +48,16 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BUILD_ARGB
|
||||
// TODO: remove lua requirement from x11_init_window
|
||||
#include "llua.h"
|
||||
|
||||
#include "gui.h"
|
||||
|
||||
/* true if use_argb_visual=true and argb visual was found*/
|
||||
extern bool have_argb_visual;
|
||||
#endif /* BUILD_ARGB */
|
||||
|
||||
#define ATOM(a) XInternAtom(display, #a, False)
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
enum window_type {
|
||||
TYPE_NORMAL = 0,
|
||||
TYPE_DOCK,
|
||||
TYPE_PANEL,
|
||||
TYPE_DESKTOP,
|
||||
TYPE_OVERRIDE,
|
||||
TYPE_UTILITY
|
||||
};
|
||||
|
||||
enum window_hints {
|
||||
HINT_UNDECORATED = 0,
|
||||
HINT_BELOW,
|
||||
HINT_ABOVE,
|
||||
HINT_STICKY,
|
||||
HINT_SKIP_TASKBAR,
|
||||
HINT_SKIP_PAGER
|
||||
};
|
||||
|
||||
#define SET_HINT(mask, hint) (mask |= (1 << (hint)))
|
||||
#define TEST_HINT(mask, hint) (mask & (1 << (hint)))
|
||||
#endif
|
||||
|
||||
extern Display *display;
|
||||
|
||||
struct conky_x11_window {
|
||||
@@ -99,10 +83,10 @@ struct conky_x11_window {
|
||||
#ifdef BUILD_XFT
|
||||
XftDraw *xftdraw;
|
||||
#endif /*BUILD_XFT*/
|
||||
#ifdef BUILD_MOUSE_EVENTS
|
||||
#if defined(BUILD_MOUSE_EVENTS) || defined(BUILD_XINPUT)
|
||||
// Don't feature gate with BUILD_XINPUT; controls fallback.
|
||||
std::int32_t xi_opcode;
|
||||
#endif /* BUILD_MOUSE_EVENTS */
|
||||
#endif /* BUILD_MOUSE_EVENTS || BUILD_XINPUT */
|
||||
|
||||
int width;
|
||||
int height;
|
||||
@@ -113,8 +97,8 @@ struct conky_x11_window {
|
||||
};
|
||||
|
||||
extern struct conky_x11_window window;
|
||||
extern conky::simple_config_setting<std::string> display_name;
|
||||
|
||||
void init_x11();
|
||||
void destroy_window(void);
|
||||
void create_gc(void);
|
||||
void set_transparent_background(Window win);
|
||||
@@ -195,54 +179,4 @@ void xdbe_swap_buffers(void);
|
||||
void xpmdb_swap_buffers(void);
|
||||
#endif /* BUILD_XDBE */
|
||||
|
||||
namespace priv {
|
||||
class out_to_x_setting : public conky::simple_config_setting<bool> {
|
||||
typedef conky::simple_config_setting<bool> Base;
|
||||
|
||||
protected:
|
||||
virtual void lua_setter(lua::state &l, bool init);
|
||||
virtual void cleanup(lua::state &l);
|
||||
|
||||
public:
|
||||
out_to_x_setting() : Base("out_to_x", true, false) {}
|
||||
};
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
class use_xdbe_setting : public conky::simple_config_setting<bool> {
|
||||
typedef conky::simple_config_setting<bool> Base;
|
||||
|
||||
bool set_up(lua::state &l);
|
||||
|
||||
protected:
|
||||
virtual void lua_setter(lua::state &l, bool init);
|
||||
|
||||
public:
|
||||
use_xdbe_setting() : Base("double_buffer", false, false) {}
|
||||
};
|
||||
|
||||
#else
|
||||
class use_xpmdb_setting : public conky::simple_config_setting<bool> {
|
||||
typedef conky::simple_config_setting<bool> Base;
|
||||
|
||||
bool set_up(lua::state &l);
|
||||
|
||||
protected:
|
||||
virtual void lua_setter(lua::state &l, bool init);
|
||||
|
||||
public:
|
||||
use_xpmdb_setting() : Base("double_buffer", false, false) {}
|
||||
};
|
||||
#endif
|
||||
} /* namespace priv */
|
||||
|
||||
extern priv::out_to_x_setting out_to_x;
|
||||
|
||||
#ifdef BUILD_XFT
|
||||
extern conky::simple_config_setting<bool> use_xft;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_XDBE
|
||||
extern priv::use_xdbe_setting use_xdbe;
|
||||
#else
|
||||
extern priv::use_xpmdb_setting use_xpmdb;
|
||||
#endif
|
||||
#endif /* CONKY_X11_H */
|
||||
|
Reference in New Issue
Block a user