1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-30 02:28:31 +00:00

Update DPI when changed in resource manager (#1878)

* Update xft_dpi on property change
  * Added fallback calculation when Xft is disabled.
* Removed display_width/height and replaced it with workarea for
  consistency.
* Make DPI work on X11 when Xft is disabled
* Make find_subwindow more specific, rename it

Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
This commit is contained in:
Tin Švagelj 2024-05-01 14:55:05 +00:00 committed by GitHub
parent 384bbed0df
commit 7b44b2a27b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 104 additions and 53 deletions

View File

@ -49,6 +49,7 @@
#include <X11/extensions/XInput2.h> #include <X11/extensions/XInput2.h>
#undef COUNT #undef COUNT
#endif /* BUILD_XINPUT */ #endif /* BUILD_XINPUT */
#include <X11/Xresource.h>
#include <cstdint> #include <cstdint>
#include <iostream> #include <iostream>
@ -81,9 +82,7 @@ extern int need_to_update;
int get_border_total(); int get_border_total();
extern conky::range_config_setting<int> maximum_width; extern conky::range_config_setting<int> maximum_width;
extern Colour current_color; extern Colour current_color;
#ifdef BUILD_XFT static float screen_dpi = -1;
static int xft_dpi = -1;
#endif /* BUILD_XFT */
/* for x_fonts */ /* for x_fonts */
struct x_font_list { struct x_font_list {
@ -147,16 +146,36 @@ struct _x11_stuff_s {
#endif #endif
} x11_stuff; } x11_stuff;
void update_dpi() {
// Add XRandR support if used
// See dunst PR: https://github.com/dunst-project/dunst/pull/608
#ifdef BUILD_XFT
if (screen_dpi > 0) return;
if (use_xft.get(*state)) {
XrmDatabase db = XrmGetDatabase(display);
if (db != nullptr) {
char *xrmType;
XrmValue xrmValue;
if (XrmGetResource(db, "Xft.dpi", "Xft.dpi", &xrmType, &xrmValue)) {
screen_dpi = strtof(xrmValue.addr, NULL);
}
} else {
auto dpi = XGetDefault(display, "Xft", "dpi");
if (dpi) { screen_dpi = strtof(dpi, nullptr); }
}
}
#endif /* BUILD_XFT */
if (screen_dpi > 0) return;
screen_dpi = static_cast<float>(DisplayWidth(display, screen)) * 25.4 /
static_cast<float>(DisplayWidthMM(display, screen));
}
static void X11_create_window() { static void X11_create_window() {
if (!window.window) { return; } if (!window.window) { return; }
setup_fonts(); setup_fonts();
load_fonts(utf8_mode.get(*state)); load_fonts(utf8_mode.get(*state));
#ifdef BUILD_XFT update_dpi();
if (use_xft.get(*state)) {
auto dpi = XGetDefault(display, "Xft", "dpi");
if (dpi) { xft_dpi = strtol(dpi, nullptr, 10); }
}
#endif /* BUILD_XFT */
update_text_area(); /* to position text/window on screen */ update_text_area(); /* to position text/window on screen */
#ifdef OWN_WINDOW #ifdef OWN_WINDOW
@ -713,19 +732,31 @@ bool handle_event<x_event_handler::PROPERTY_NOTIFY>(
get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom); get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom);
} }
#ifdef USE_ARGB if (ev.xproperty.atom == 0) return false;
if (have_argb_visual) return true;
#endif
if (ev.xproperty.atom == ATOM(_XROOTPMAP_ID) || if (ev.xproperty.atom == XA_RESOURCE_MANAGER) {
ev.xproperty.atom == ATOM(_XROOTMAP_ID)) { update_x11_resource_db();
if (forced_redraw.get(*state)) { update_x11_workarea();
draw_stuff(); screen_dpi = -1;
next_update_time = get_time(); update_dpi();
need_to_update = 1; return true;
}
if (!have_argb_visual) {
Atom _XROOTPMAP_ID = XInternAtom(display, "_XROOTPMAP_ID", True);
Atom _XROOTMAP_ID = XInternAtom(display, "_XROOTMAP_ID", True);
if (ev.xproperty.atom == _XROOTPMAP_ID ||
ev.xproperty.atom == _XROOTMAP_ID) {
if (forced_redraw.get(*state)) {
draw_stuff();
next_update_time = get_time();
need_to_update = 1;
}
return true;
} }
} }
return true;
return false;
} }
template <> template <>
@ -947,11 +978,9 @@ void display_output_x11::move_win(int x, int y) {
const float PIXELS_PER_INCH = 96.0; const float PIXELS_PER_INCH = 96.0;
float display_output_x11::get_dpi_scale() { float display_output_x11::get_dpi_scale() {
#ifdef BUILD_XFT if (screen_dpi > 0) {
if (use_xft.get(*state) && xft_dpi > 0) { return static_cast<float>(screen_dpi) / PIXELS_PER_INCH;
return static_cast<float>(xft_dpi) / PIXELS_PER_INCH;
} }
#endif /* BUILD_XFT */
return 1.0; return 1.0;
} }

View File

@ -45,8 +45,6 @@
#endif #endif
/* basic display attributes */ /* basic display attributes */
int display_width;
int display_height;
int screen; int screen;
/* workarea where window / text is aligned (from _NET_WORKAREA on X11) */ /* workarea where window / text is aligned (from _NET_WORKAREA on X11) */

View File

@ -168,8 +168,6 @@ inline bool TEST_HINT(uint16_t mask, window_hints hint) {
#ifdef BUILD_X11 #ifdef BUILD_X11
extern Display *display; extern Display *display;
#endif /* BUILD_X11 */ #endif /* BUILD_X11 */
extern int display_width;
extern int display_height;
extern int screen; extern int screen;
extern int workarea[4]; extern int workarea[4];

View File

@ -90,6 +90,7 @@ extern "C" {
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_errors.h> #include <xcb/xcb_errors.h>
#endif #endif
#include <X11/Xresource.h>
} }
/* some basic X11 stuff */ /* some basic X11 stuff */
@ -106,9 +107,8 @@ struct conky_x11_window window;
bool have_argb_visual = false; bool have_argb_visual = false;
/* local prototypes */ /* local prototypes */
static void update_workarea();
static Window find_desktop_window(Window *p_root, Window *p_desktop); static Window find_desktop_window(Window *p_root, Window *p_desktop);
static Window find_subwindow(Window win, int w, int h); static Window find_desktop_window_impl(Window win, int w, int h);
/* WARNING, this type not in Xlib spec */ /* WARNING, this type not in Xlib spec */
static int x11_error_handler(Display *d, XErrorEvent *err) { static int x11_error_handler(Display *d, XErrorEvent *err) {
@ -260,13 +260,15 @@ void init_x11() {
info.x11.desktop.name.clear(); info.x11.desktop.name.clear();
screen = DefaultScreen(display); screen = DefaultScreen(display);
display_width = DisplayWidth(display, screen);
display_height = DisplayHeight(display, screen); XSetErrorHandler(&x11_error_handler);
XSetIOErrorHandler(&x11_ioerror_handler);
update_x11_resource_db(true);
update_x11_workarea();
get_x11_desktop_info(display, 0); get_x11_desktop_info(display, 0);
update_workarea();
#ifdef HAVE_XCB_ERRORS #ifdef HAVE_XCB_ERRORS
auto connection = xcb_connect(NULL, NULL); auto connection = xcb_connect(NULL, NULL);
if (!xcb_connection_has_error(connection)) { if (!xcb_connection_has_error(connection)) {
@ -275,11 +277,6 @@ void init_x11() {
} }
} }
#endif /* HAVE_XCB_ERRORS */ #endif /* HAVE_XCB_ERRORS */
/* WARNING, this type not in Xlib spec */
XSetErrorHandler(&x11_error_handler);
XSetIOErrorHandler(&x11_ioerror_handler);
DBGP("leave init_x11()"); DBGP("leave init_x11()");
} }
@ -291,12 +288,39 @@ void deinit_x11() {
} }
} }
static void update_workarea() { // Source: dunst
// https://github.com/bebehei/dunst/blob/1bc3237a359f37905426012c0cca90d71c4b3b18/src/x11/x.c#L463
void update_x11_resource_db(bool first_run) {
XrmDatabase db;
XTextProperty prop;
Window root;
XFlush(display);
root = RootWindow(display, screen);
XLockDisplay(display);
if (XGetTextProperty(display, root, &prop, XA_RESOURCE_MANAGER)) {
if (!first_run) {
db = XrmGetDatabase(display);
XrmDestroyDatabase(db);
}
db = XrmGetStringDatabase((const char *)prop.value);
XrmSetDatabase(display, db);
}
XUnlockDisplay(display);
XFlush(display);
XSync(display, false);
}
void update_x11_workarea() {
/* default work area is display */ /* default work area is display */
workarea[0] = 0; workarea[0] = 0;
workarea[1] = 0; workarea[1] = 0;
workarea[2] = display_width; workarea[2] = DisplayWidth(display, screen);
workarea[3] = display_height; workarea[3] = DisplayHeight(display, screen);
#ifdef BUILD_XINERAMA #ifdef BUILD_XINERAMA
/* if xinerama is being used, adjust workarea to the head's area */ /* if xinerama is being used, adjust workarea to the head's area */
@ -344,9 +368,12 @@ static Window find_desktop_window(Window root) {
Window desktop = root; Window desktop = root;
/* get subwindows from root */ /* get subwindows from root */
desktop = find_subwindow(root, -1, -1); int display_width = DisplayWidth(display, screen);
update_workarea(); int display_height = DisplayHeight(display, screen);
desktop = find_subwindow(desktop, workarea[2], workarea[3]); desktop = find_desktop_window_impl(root, display_width, display_height);
update_x11_workarea();
desktop = find_desktop_window_impl(desktop, workarea[2] - workarea[0],
workarea[3] - workarea[1]);
if (desktop != root) { if (desktop != root) {
NORM_ERR("desktop window (0x%lx) is subwindow of root window (0x%lx)", NORM_ERR("desktop window (0x%lx) is subwindow of root window (0x%lx)",
@ -514,13 +541,11 @@ void x11_init_window(lua::state &l, bool own) {
0, 0,
0}; 0};
flags |= CWBackPixel; flags |= CWBackPixel;
#ifdef BUILD_ARGB
if (have_argb_visual) { if (have_argb_visual) {
attrs.colormap = window.colourmap; attrs.colormap = window.colourmap;
flags &= ~CWBackPixel; flags &= ~CWBackPixel;
flags |= CWBorderPixel | CWColormap; flags |= CWBorderPixel | CWColormap;
} }
#endif /* BUILD_ARGB */
/* Parent is desktop window (which might be a child of root) */ /* Parent is desktop window (which might be a child of root) */
window.window = window.window =
@ -557,13 +582,11 @@ void x11_init_window(lua::state &l, bool own) {
Atom xa; Atom xa;
flags |= CWBackPixel; flags |= CWBackPixel;
#ifdef BUILD_ARGB
if (have_argb_visual) { if (have_argb_visual) {
attrs.colormap = window.colourmap; attrs.colormap = window.colourmap;
flags &= ~CWBackPixel; flags &= ~CWBackPixel;
flags |= CWBorderPixel | CWColormap; flags |= CWBorderPixel | CWColormap;
} }
#endif /* BUILD_ARGB */
if (own_window_type.get(l) == window_type::DOCK) { if (own_window_type.get(l) == window_type::DOCK) {
window.x = window.y = 0; window.x = window.y = 0;
@ -868,7 +891,7 @@ void x11_init_window(lua::state &l, bool own) {
DBGP("leave x11_init_window()"); DBGP("leave x11_init_window()");
} }
static Window find_subwindow(Window win, int w, int h) { static Window find_desktop_window_impl(Window win, int w, int h) {
unsigned int i, j; unsigned int i, j;
Window troot, parent, *children; Window troot, parent, *children;
unsigned int n; unsigned int n;
@ -880,13 +903,11 @@ static Window find_subwindow(Window win, int w, int h) {
for (j = 0; j < n; j++) { for (j = 0; j < n; j++) {
XWindowAttributes attrs; XWindowAttributes attrs;
if (XGetWindowAttributes(display, children[j], &attrs) != 0) { if (XGetWindowAttributes(display, children[j], &attrs) != 0) {
/* Window must be mapped and same size as display or /* Window must be mapped and same size as display or
* work space */ * work space */
if (attrs.map_state != 0 && if (attrs.map_state == IsViewable && attrs.override_redirect == false &&
((attrs.width == display_width && attrs.height == display_height) || ((attrs.width == w && attrs.height == h))) {
(attrs.width == w && attrs.height == h))) {
win = children[j]; win = children[j];
break; break;
} }
@ -1116,6 +1137,9 @@ void set_struts(alignment align) {
if (strut != None) { if (strut != None) {
long sizes[STRUT_COUNT] = {0}; long sizes[STRUT_COUNT] = {0};
int display_width = workarea[2] - workarea[0];
int display_height = workarea[3] - workarea[1];
switch (horizontal_alignment(align)) { switch (horizontal_alignment(align)) {
case axis_align::START: case axis_align::START:
sizes[*x11_strut::LEFT] = sizes[*x11_strut::LEFT] =

View File

@ -98,6 +98,8 @@ struct conky_x11_window {
extern struct conky_x11_window window; extern struct conky_x11_window window;
void update_x11_resource_db(bool first_run = false);
void update_x11_workarea();
void init_x11(); void init_x11();
void destroy_window(void); void destroy_window(void);
void create_gc(void); void create_gc(void);