feat: add dpi detection and configuration for mouse distance

This commit is contained in:
retoor 2026-01-28 16:55:00 +01:00
parent b0b1a854cf
commit df34716ea5
17 changed files with 47 additions and 1 deletions

BIN
bin/dwn

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -39,6 +39,7 @@ struct Config {
int panel_height;
int gap;
char font_name[128];
double mouse_distance_dpi;
ColorScheme colors;
float default_master_ratio;

View File

@ -215,6 +215,9 @@ typedef struct {
int last_mouse_x;
int last_mouse_y;
bool mouse_tracking_initialized;
double pixels_per_cm;
bool dpi_auto_detected;
} DWNState;
#define PHASE_OFFSET_PANEL_BG 0.0f

View File

@ -61,6 +61,7 @@ void config_set_defaults(Config *cfg)
cfg->panel_height = DEFAULT_PANEL_HEIGHT;
cfg->gap = DEFAULT_GAP;
strncpy(cfg->font_name, "fixed", sizeof(cfg->font_name) - 1);
cfg->mouse_distance_dpi = 0.0;
cfg->default_master_ratio = 0.55f;
cfg->default_master_count = 1;
@ -158,6 +159,9 @@ static void handle_config_entry(const char *section, const char *key,
cfg->gap = (val >= 0 && val <= 100) ? val : DEFAULT_GAP;
} else if (strcmp(key, "font") == 0) {
strncpy(cfg->font_name, value, sizeof(cfg->font_name) - 1);
} else if (strcmp(key, "mouse_distance_dpi") == 0) {
double val = atof(value);
cfg->mouse_distance_dpi = (val > 0.0) ? val : 0.0;
}
} else if (strcmp(section, "layout") == 0) {
if (strcmp(key, "master_ratio") == 0) {

View File

@ -218,6 +218,42 @@ static void handle_xi2_event(XGenericEventCookie *cookie)
XFreeEventData(dwn->display, cookie);
}
static double calculate_pixels_per_cm(void)
{
if (dwn->config->mouse_distance_dpi > 0.0) {
LOG_DEBUG("Using manual DPI override: %.1f", dwn->config->mouse_distance_dpi);
return dwn->config->mouse_distance_dpi / 2.54;
}
int width_mm = DisplayWidthMM(dwn->display, dwn->screen);
int height_mm = DisplayHeightMM(dwn->display, dwn->screen);
if (width_mm > 0 && height_mm > 0) {
double diag_pixels = sqrt((double)dwn->screen_width * dwn->screen_width +
(double)dwn->screen_height * dwn->screen_height);
double diag_mm = sqrt((double)width_mm * width_mm + (double)height_mm * height_mm);
double diag_cm = diag_mm / 10.0;
double pixels_per_cm = diag_pixels / diag_cm;
if (pixels_per_cm >= 20.0 && pixels_per_cm <= 200.0) {
dwn->dpi_auto_detected = true;
double dpi = pixels_per_cm * 2.54;
LOG_INFO("Auto-detected DPI: %.1f (%.2f pixels/cm) from EDID: %dx%dmm for %dx%dpx",
dpi, pixels_per_cm, width_mm, height_mm,
dwn->screen_width, dwn->screen_height);
return pixels_per_cm;
} else {
LOG_WARN("EDID data appears corrupt: %.1f pixels/cm detected, ignoring",
pixels_per_cm);
}
}
LOG_WARN("Could not detect screen DPI from EDID, using default 96 DPI");
dwn->dpi_auto_detected = false;
return 37.8;
}
static void init_monitors(void)
{
if (!XineramaIsActive(dwn->display)) {
@ -842,6 +878,8 @@ int dwn_init(void)
extern void config_init_colors(Config *cfg);
config_init_colors(dwn->config);
dwn->pixels_per_cm = calculate_pixels_per_cm();
dwn->font = XLoadQueryFont(dwn->display, dwn->config->font_name);
if (dwn->font == NULL) {
dwn->font = XLoadQueryFont(dwn->display, "fixed");

View File

@ -1348,7 +1348,7 @@ static void panel_render_mouse_distance(Panel *panel, int x, int *width)
int text_y = panel_text_y(panel->height);
char buf[32];
double cm = dwn->mouse_distance_pixels / 37.8;
double cm = dwn->mouse_distance_pixels / dwn->pixels_per_cm;
int len;
if (cm >= 100000.0) {