mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-17 02:25:09 +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>
|
||||
#undef COUNT
|
||||
#endif /* BUILD_XINPUT */
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
@ -81,9 +82,7 @@ extern int need_to_update;
|
||||
int get_border_total();
|
||||
extern conky::range_config_setting<int> maximum_width;
|
||||
extern Colour current_color;
|
||||
#ifdef BUILD_XFT
|
||||
static int xft_dpi = -1;
|
||||
#endif /* BUILD_XFT */
|
||||
static float screen_dpi = -1;
|
||||
|
||||
/* for x_fonts */
|
||||
struct x_font_list {
|
||||
@ -147,16 +146,36 @@ struct _x11_stuff_s {
|
||||
#endif
|
||||
} x11_stuff;
|
||||
|
||||
void update_dpi() {
|
||||
// Add XRandR support if used
|
||||
// See dunst PR: https://github.com/dunst-project/dunst/pull/608
|
||||
|
||||
#ifdef BUILD_XFT
|
||||
if (screen_dpi > 0) return;
|
||||
if (use_xft.get(*state)) {
|
||||
XrmDatabase db = XrmGetDatabase(display);
|
||||
if (db != nullptr) {
|
||||
char *xrmType;
|
||||
XrmValue xrmValue;
|
||||
if (XrmGetResource(db, "Xft.dpi", "Xft.dpi", &xrmType, &xrmValue)) {
|
||||
screen_dpi = strtof(xrmValue.addr, NULL);
|
||||
}
|
||||
} else {
|
||||
auto dpi = XGetDefault(display, "Xft", "dpi");
|
||||
if (dpi) { screen_dpi = strtof(dpi, nullptr); }
|
||||
}
|
||||
}
|
||||
#endif /* BUILD_XFT */
|
||||
if (screen_dpi > 0) return;
|
||||
screen_dpi = static_cast<float>(DisplayWidth(display, screen)) * 25.4 /
|
||||
static_cast<float>(DisplayWidthMM(display, screen));
|
||||
}
|
||||
|
||||
static void X11_create_window() {
|
||||
if (!window.window) { return; }
|
||||
setup_fonts();
|
||||
load_fonts(utf8_mode.get(*state));
|
||||
#ifdef BUILD_XFT
|
||||
if (use_xft.get(*state)) {
|
||||
auto dpi = XGetDefault(display, "Xft", "dpi");
|
||||
if (dpi) { xft_dpi = strtol(dpi, nullptr, 10); }
|
||||
}
|
||||
#endif /* BUILD_XFT */
|
||||
update_dpi();
|
||||
update_text_area(); /* to position text/window on screen */
|
||||
|
||||
#ifdef OWN_WINDOW
|
||||
@ -713,20 +732,32 @@ bool handle_event<x_event_handler::PROPERTY_NOTIFY>(
|
||||
get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom);
|
||||
}
|
||||
|
||||
#ifdef USE_ARGB
|
||||
if (have_argb_visual) return true;
|
||||
#endif
|
||||
if (ev.xproperty.atom == 0) return false;
|
||||
|
||||
if (ev.xproperty.atom == ATOM(_XROOTPMAP_ID) ||
|
||||
ev.xproperty.atom == ATOM(_XROOTMAP_ID)) {
|
||||
if (ev.xproperty.atom == XA_RESOURCE_MANAGER) {
|
||||
update_x11_resource_db();
|
||||
update_x11_workarea();
|
||||
screen_dpi = -1;
|
||||
update_dpi();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!have_argb_visual) {
|
||||
Atom _XROOTPMAP_ID = XInternAtom(display, "_XROOTPMAP_ID", True);
|
||||
Atom _XROOTMAP_ID = XInternAtom(display, "_XROOTMAP_ID", True);
|
||||
if (ev.xproperty.atom == _XROOTPMAP_ID ||
|
||||
ev.xproperty.atom == _XROOTMAP_ID) {
|
||||
if (forced_redraw.get(*state)) {
|
||||
draw_stuff();
|
||||
next_update_time = get_time();
|
||||
need_to_update = 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool handle_event<x_event_handler::EXPOSE>(conky::display_output_x11 *surface,
|
||||
@ -947,11 +978,9 @@ void display_output_x11::move_win(int x, int y) {
|
||||
|
||||
const float PIXELS_PER_INCH = 96.0;
|
||||
float display_output_x11::get_dpi_scale() {
|
||||
#ifdef BUILD_XFT
|
||||
if (use_xft.get(*state) && xft_dpi > 0) {
|
||||
return static_cast<float>(xft_dpi) / PIXELS_PER_INCH;
|
||||
if (screen_dpi > 0) {
|
||||
return static_cast<float>(screen_dpi) / PIXELS_PER_INCH;
|
||||
}
|
||||
#endif /* BUILD_XFT */
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,6 @@
|
||||
#endif
|
||||
|
||||
/* basic display attributes */
|
||||
int display_width;
|
||||
int display_height;
|
||||
int screen;
|
||||
|
||||
/* workarea where window / text is aligned (from _NET_WORKAREA on X11) */
|
||||
|
@ -168,8 +168,6 @@ inline bool TEST_HINT(uint16_t mask, window_hints hint) {
|
||||
#ifdef BUILD_X11
|
||||
extern Display *display;
|
||||
#endif /* BUILD_X11 */
|
||||
extern int display_width;
|
||||
extern int display_height;
|
||||
extern int screen;
|
||||
extern int workarea[4];
|
||||
|
||||
|
76
src/x11.cc
76
src/x11.cc
@ -90,6 +90,7 @@ extern "C" {
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_errors.h>
|
||||
#endif
|
||||
#include <X11/Xresource.h>
|
||||
}
|
||||
|
||||
/* some basic X11 stuff */
|
||||
@ -106,9 +107,8 @@ struct conky_x11_window window;
|
||||
bool have_argb_visual = false;
|
||||
|
||||
/* local prototypes */
|
||||
static void update_workarea();
|
||||
static Window find_desktop_window(Window *p_root, Window *p_desktop);
|
||||
static Window find_subwindow(Window win, int w, int h);
|
||||
static Window find_desktop_window_impl(Window win, int w, int h);
|
||||
|
||||
/* WARNING, this type not in Xlib spec */
|
||||
static int x11_error_handler(Display *d, XErrorEvent *err) {
|
||||
@ -260,13 +260,15 @@ void init_x11() {
|
||||
info.x11.desktop.name.clear();
|
||||
|
||||
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);
|
||||
|
||||
update_workarea();
|
||||
|
||||
#ifdef HAVE_XCB_ERRORS
|
||||
auto connection = xcb_connect(NULL, NULL);
|
||||
if (!xcb_connection_has_error(connection)) {
|
||||
@ -275,11 +277,6 @@ void init_x11() {
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_XCB_ERRORS */
|
||||
|
||||
/* WARNING, this type not in Xlib spec */
|
||||
XSetErrorHandler(&x11_error_handler);
|
||||
XSetIOErrorHandler(&x11_ioerror_handler);
|
||||
|
||||
DBGP("leave init_x11()");
|
||||
}
|
||||
|
||||
@ -291,12 +288,39 @@ void deinit_x11() {
|
||||
}
|
||||
}
|
||||
|
||||
static void update_workarea() {
|
||||
// Source: dunst
|
||||
// https://github.com/bebehei/dunst/blob/1bc3237a359f37905426012c0cca90d71c4b3b18/src/x11/x.c#L463
|
||||
void update_x11_resource_db(bool first_run) {
|
||||
XrmDatabase db;
|
||||
XTextProperty prop;
|
||||
Window root;
|
||||
|
||||
XFlush(display);
|
||||
|
||||
root = RootWindow(display, screen);
|
||||
|
||||
XLockDisplay(display);
|
||||
if (XGetTextProperty(display, root, &prop, XA_RESOURCE_MANAGER)) {
|
||||
if (!first_run) {
|
||||
db = XrmGetDatabase(display);
|
||||
XrmDestroyDatabase(db);
|
||||
}
|
||||
|
||||
db = XrmGetStringDatabase((const char *)prop.value);
|
||||
XrmSetDatabase(display, db);
|
||||
}
|
||||
XUnlockDisplay(display);
|
||||
|
||||
XFlush(display);
|
||||
XSync(display, false);
|
||||
}
|
||||
|
||||
void update_x11_workarea() {
|
||||
/* default work area is display */
|
||||
workarea[0] = 0;
|
||||
workarea[1] = 0;
|
||||
workarea[2] = display_width;
|
||||
workarea[3] = display_height;
|
||||
workarea[2] = DisplayWidth(display, screen);
|
||||
workarea[3] = DisplayHeight(display, screen);
|
||||
|
||||
#ifdef BUILD_XINERAMA
|
||||
/* if xinerama is being used, adjust workarea to the head's area */
|
||||
@ -344,9 +368,12 @@ static Window find_desktop_window(Window root) {
|
||||
Window desktop = root;
|
||||
|
||||
/* get subwindows from root */
|
||||
desktop = find_subwindow(root, -1, -1);
|
||||
update_workarea();
|
||||
desktop = find_subwindow(desktop, workarea[2], workarea[3]);
|
||||
int display_width = DisplayWidth(display, screen);
|
||||
int display_height = DisplayHeight(display, screen);
|
||||
desktop = find_desktop_window_impl(root, display_width, display_height);
|
||||
update_x11_workarea();
|
||||
desktop = find_desktop_window_impl(desktop, workarea[2] - workarea[0],
|
||||
workarea[3] - workarea[1]);
|
||||
|
||||
if (desktop != root) {
|
||||
NORM_ERR("desktop window (0x%lx) is subwindow of root window (0x%lx)",
|
||||
@ -514,13 +541,11 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
0,
|
||||
0};
|
||||
flags |= CWBackPixel;
|
||||
#ifdef BUILD_ARGB
|
||||
if (have_argb_visual) {
|
||||
attrs.colormap = window.colourmap;
|
||||
flags &= ~CWBackPixel;
|
||||
flags |= CWBorderPixel | CWColormap;
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
|
||||
/* Parent is desktop window (which might be a child of root) */
|
||||
window.window =
|
||||
@ -557,13 +582,11 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
Atom xa;
|
||||
|
||||
flags |= CWBackPixel;
|
||||
#ifdef BUILD_ARGB
|
||||
if (have_argb_visual) {
|
||||
attrs.colormap = window.colourmap;
|
||||
flags &= ~CWBackPixel;
|
||||
flags |= CWBorderPixel | CWColormap;
|
||||
}
|
||||
#endif /* BUILD_ARGB */
|
||||
|
||||
if (own_window_type.get(l) == window_type::DOCK) {
|
||||
window.x = window.y = 0;
|
||||
@ -868,7 +891,7 @@ void x11_init_window(lua::state &l, bool own) {
|
||||
DBGP("leave x11_init_window()");
|
||||
}
|
||||
|
||||
static Window find_subwindow(Window win, int w, int h) {
|
||||
static Window find_desktop_window_impl(Window win, int w, int h) {
|
||||
unsigned int i, j;
|
||||
Window troot, parent, *children;
|
||||
unsigned int n;
|
||||
@ -880,13 +903,11 @@ static Window find_subwindow(Window win, int w, int h) {
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
XWindowAttributes attrs;
|
||||
|
||||
if (XGetWindowAttributes(display, children[j], &attrs) != 0) {
|
||||
/* Window must be mapped and same size as display or
|
||||
* work space */
|
||||
if (attrs.map_state != 0 &&
|
||||
((attrs.width == display_width && attrs.height == display_height) ||
|
||||
(attrs.width == w && attrs.height == h))) {
|
||||
if (attrs.map_state == IsViewable && attrs.override_redirect == false &&
|
||||
((attrs.width == w && attrs.height == h))) {
|
||||
win = children[j];
|
||||
break;
|
||||
}
|
||||
@ -1116,6 +1137,9 @@ void set_struts(alignment align) {
|
||||
if (strut != None) {
|
||||
long sizes[STRUT_COUNT] = {0};
|
||||
|
||||
int display_width = workarea[2] - workarea[0];
|
||||
int display_height = workarea[3] - workarea[1];
|
||||
|
||||
switch (horizontal_alignment(align)) {
|
||||
case axis_align::START:
|
||||
sizes[*x11_strut::LEFT] =
|
||||
|
Loading…
Reference in New Issue
Block a user