Skip to content

Commit

Permalink
added mechanism to better detect x11 scale factor
Browse files Browse the repository at this point in the history
  • Loading branch information
jgmdev committed Sep 16, 2022
1 parent de49c90 commit 86ba2e3
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 28 deletions.
9 changes: 9 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ if not get_option('source-only')

lite_deps = [lua_dep, sdl_dep, freetype_dep, pcre2_dep, libm, libdl]
endif

#===============================================================================
# Link to X11 on linux to detect scale factor when video driver is x11
#===============================================================================
if host_machine.system() == 'linux'
x_dep = dependency('X11')
lite_deps += x_dep
endif

#===============================================================================
# Install Configuration
#===============================================================================
Expand Down
87 changes: 82 additions & 5 deletions src/api/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
#endif

extern SDL_Window *window;
extern float initial_scale;
static bool got_initial_scale = false;


static const char* button_name(int button) {
Expand Down Expand Up @@ -347,11 +345,78 @@ static int f_set_cursor(lua_State *L) {
return 0;
}

#ifdef __linux__
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>

static float x11_scale_factor() {
static bool initialized = false;

if (!initialized) {
XrmInitialize();
initialized = true;
}

float scale = 0.0;
char *resourceString = XResourceManagerString(XOpenDisplay(NULL));

if (resourceString) {
XrmDatabase db = XrmGetStringDatabase(resourceString);
XrmValue value;
char *type = NULL;
float dpi = 0.0;

if (XrmGetResource(db, "Xft.dpi", "String", &type, &value)) {
if (value.addr) {
dpi = atof(value.addr);
if (dpi > 0)
scale = roundf((dpi / 96) * 100) / 100;
}
}
XrmDestroyDatabase(db);
free(resourceString);
}

return scale;
}
#endif

static float sdl_scale_factor() {
/* When not using the sdl renderer the SDL_WINDOW_ALLOW_HIGHDPI flag
causes the window to render the content pixelated, so we create
a separate window with the high dpi flag to retrieve the display
scale factor and then we destroy it.
*/
#ifndef LITE_USE_SDL_RENDERER
SDL_DisplayMode dm;
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &dm);

SDL_Window *windowHDPI = SDL_CreateWindow(
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
dm.w * 0.8, dm.h * 0.8,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN
);
#else
SDL_Window *windowHDPI = window;
#endif

float scale = ren_get_scale_factor(windowHDPI);
#ifndef LITE_USE_SDL_RENDERER
SDL_DestroyWindow(windowHDPI);
#endif

return scale;
}

static int f_get_scale(lua_State *L) {
static bool got_initial_scale = false;

/* returns the startup scale factor on first call if not 100% */
if (!got_initial_scale) {
got_initial_scale = true;
float initial_scale = sdl_scale_factor();
if (initial_scale != 1.0) {
got_initial_scale = true;
lua_pushnumber(L, initial_scale);
return 1;
}
Expand Down Expand Up @@ -379,12 +444,23 @@ static int f_get_scale(lua_State *L) {
(system_scale = strtod(env_scale, NULL)) > 0
) {
scale = system_scale;
} else if ((system_scale = ren_get_scale_factor(window)) != 1.0) {
#ifdef __linux__
} else if (
strstr(SDL_GetCurrentVideoDriver(), "x11")
&&
(system_scale = x11_scale_factor()) > 0
) {
scale = system_scale;
#endif
#if _WIN32
} else if (SDL_GetDisplayDPI(display_index, NULL, &dpi, NULL) == 0) {
scale = dpi / 96.0;
#endif
} else if (
got_initial_scale && (system_scale = sdl_scale_factor()) > 0
) {
scale = system_scale;
/* if all other methods failed use a suggested scale factor */
} else if (SDL_GetCurrentDisplayMode(display_index, &dm) == 0) {
float base_width = 1280, base_height = 720;
float dmw = (float) dm.w, dmh = (float) dm.h;
Expand All @@ -400,7 +476,8 @@ static int f_get_scale(lua_State *L) {
scale = dmh / base_height;
}
}
#endif
#endif /* __APPLE__ */
got_initial_scale = true;
lua_pushnumber(L, scale);
return 1;
}
Expand Down
24 changes: 1 addition & 23 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@


SDL_Window *window;
float initial_scale = 1.0;

static void get_exe_filename(char *buf, int sz) {
#if _WIN32
Expand Down Expand Up @@ -118,7 +117,7 @@ int main(int argc, char **argv) {
SDL_WINDOW_RESIZABLE
| SDL_WINDOW_HIDDEN
#if LITE_USE_SDL_RENDERER
/* causes pixelated rendering when not using the sdl renderer */
/* causes pixelated rendering when not using the sdl renderer and scaled */
| SDL_WINDOW_ALLOW_HIGHDPI
#endif
);
Expand All @@ -127,27 +126,6 @@ int main(int argc, char **argv) {
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &dm);
SDL_SetWindowSize(window, dm.w * 0.8, dm.h * 0.8);

/* When not using the sdl renderer the SDL_WINDOW_ALLOW_HIGHDPI flag
causes the window to render the content pixelated, so we create
a separate window with the high dpi flag to retrieve the display
scale factor and then we destroy it.
*/
#ifndef LITE_USE_SDL_RENDERER
SDL_Window *windowHDPI = SDL_CreateWindow(
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
dm.w * 0.8, dm.h * 0.8,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN
);
#else
SDL_Window *windowHDPI = window;
#endif

/* Get the system scale factor. */
initial_scale = ren_get_scale_factor(windowHDPI);
#ifndef LITE_USE_SDL_RENDERER
SDL_DestroyWindow(windowHDPI);
#endif

init_window_icon();
if (!window) {
fprintf(stderr, "Error creating lite-xl window: %s", SDL_GetError());
Expand Down

0 comments on commit 86ba2e3

Please sign in to comment.