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:
parent
384bbed0df
commit
7b44b2a27b
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) */
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
76
src/x11.cc
76
src/x11.cc
@ -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] =
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user