Skip to content

Commit

Permalink
Add high DPI support for SDL 3 backends
Browse files Browse the repository at this point in the history
Breaking change:
- The SDL platform's `InputEventHandler` function now takes an additional parameter `window`.
  • Loading branch information
mikke89 committed Dec 28, 2024
1 parent 01fc3c4 commit 56d1a21
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 37 deletions.
14 changes: 9 additions & 5 deletions Backends/RmlUi_Backend_SDL_GL2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,16 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al

#if SDL_MAJOR_VERSION >= 3
auto CreateWindow = [&]() {
const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale));
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale));
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
SDL_Window* window = SDL_CreateWindowWithProperties(props);
SDL_DestroyProperties(props);
return window;
Expand Down Expand Up @@ -249,6 +251,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
#define RMLSDL_WINDOW_EVENTS_BEGIN
#define RMLSDL_WINDOW_EVENTS_END
auto GetKey = [](const SDL_Event& event) { return event.key.key; };
auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); };
constexpr auto event_quit = SDL_EVENT_QUIT;
constexpr auto event_key_down = SDL_EVENT_KEY_DOWN;
constexpr auto event_window_size_changed = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
Expand All @@ -264,6 +267,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
} \
break;
auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; };
auto GetDisplayScale = []() { return 1.f; };
constexpr auto event_quit = SDL_QUIT;
constexpr auto event_key_down = SDL_KEYDOWN;
constexpr auto event_window_size_changed = SDL_WINDOWEVENT_SIZE_CHANGED;
Expand Down Expand Up @@ -295,13 +299,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
propagate_event = false;
const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev));
const int key_modifier = RmlSDL::GetKeyModifierState();
const float native_dp_ratio = 1.f;
const float native_dp_ratio = GetDisplayScale();

// See if we have any global shortcuts that take priority over the context.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true))
break;
// Otherwise, hand the event over to the context by calling the input handler as normal.
if (!RmlSDL::InputEventHandler(context, ev))
if (!RmlSDL::InputEventHandler(context, data->window, ev))
break;
// The key was not consumed by the context either, try keyboard shortcuts of lower priority.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false))
Expand All @@ -324,7 +328,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
}

if (propagate_event)
RmlSDL::InputEventHandler(context, ev);
RmlSDL::InputEventHandler(context, data->window, ev);

has_event = SDL_PollEvent(&ev);
}
Expand Down
14 changes: 9 additions & 5 deletions Backends/RmlUi_Backend_SDL_GL3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,16 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

#if SDL_MAJOR_VERSION >= 3
const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale));
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale));
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
SDL_Window* window = SDL_CreateWindowWithProperties(props);
SDL_DestroyProperties(props);
#else
Expand Down Expand Up @@ -272,6 +274,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
#define RMLSDL_WINDOW_EVENTS_BEGIN
#define RMLSDL_WINDOW_EVENTS_END
auto GetKey = [](const SDL_Event& event) { return event.key.key; };
auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); };
constexpr auto event_quit = SDL_EVENT_QUIT;
constexpr auto event_key_down = SDL_EVENT_KEY_DOWN;
constexpr auto event_window_size_changed = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
Expand All @@ -287,6 +290,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
} \
break;
auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; };
auto GetDisplayScale = []() { return 1.f; };
constexpr auto event_quit = SDL_QUIT;
constexpr auto event_key_down = SDL_KEYDOWN;
constexpr auto event_window_size_changed = SDL_WINDOWEVENT_SIZE_CHANGED;
Expand Down Expand Up @@ -318,13 +322,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
propagate_event = false;
const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev));
const int key_modifier = RmlSDL::GetKeyModifierState();
const float native_dp_ratio = 1.f;
const float native_dp_ratio = GetDisplayScale();

// See if we have any global shortcuts that take priority over the context.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true))
break;
// Otherwise, hand the event over to the context by calling the input handler as normal.
if (!RmlSDL::InputEventHandler(context, ev))
if (!RmlSDL::InputEventHandler(context, data->window, ev))
break;
// The key was not consumed by the context either, try keyboard shortcuts of lower priority.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false))
Expand All @@ -347,7 +351,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
}

if (propagate_event)
RmlSDL::InputEventHandler(context, ev);
RmlSDL::InputEventHandler(context, data->window, ev);

has_event = SDL_PollEvent(&ev);
}
Expand Down
14 changes: 9 additions & 5 deletions Backends/RmlUi_Backend_SDL_SDLrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");

#if SDL_MAJOR_VERSION >= 3
const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale));
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale));
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
SDL_Window* window = SDL_CreateWindowWithProperties(props);
SDL_DestroyProperties(props);
#else
Expand Down Expand Up @@ -167,11 +169,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call

#if SDL_MAJOR_VERSION >= 3
auto GetKey = [](const SDL_Event& event) { return event.key.key; };
auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); };
constexpr auto event_quit = SDL_EVENT_QUIT;
constexpr auto event_key_down = SDL_EVENT_KEY_DOWN;
bool has_event = false;
#else
auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; };
auto GetDisplayScale = []() { return 1.f; };
constexpr auto event_quit = SDL_QUIT;
constexpr auto event_key_down = SDL_KEYDOWN;
int has_event = 0;
Expand Down Expand Up @@ -202,13 +206,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
propagate_event = false;
const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev));
const int key_modifier = RmlSDL::GetKeyModifierState();
const float native_dp_ratio = 1.f;
const float native_dp_ratio = GetDisplayScale();

// See if we have any global shortcuts that take priority over the context.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true))
break;
// Otherwise, hand the event over to the context by calling the input handler as normal.
if (!RmlSDL::InputEventHandler(context, ev))
if (!RmlSDL::InputEventHandler(context, data->window, ev))
break;
// The key was not consumed by the context either, try keyboard shortcuts of lower priority.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false))
Expand All @@ -219,7 +223,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
}

if (propagate_event)
RmlSDL::InputEventHandler(context, ev);
RmlSDL::InputEventHandler(context, data->window, ev);

has_event = SDL_PollEvent(&ev);
}
Expand Down
14 changes: 9 additions & 5 deletions Backends/RmlUi_Backend_SDL_VK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");

#if SDL_MAJOR_VERSION >= 3
const float window_size_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_name);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, int(width * window_size_scale));
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, int(height * window_size_scale));
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN, true);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, allow_resize);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true);
SDL_Window* window = SDL_CreateWindowWithProperties(props);
SDL_DestroyProperties(props);
auto CreateSurface = [](VkInstance instance, VkSurfaceKHR* out_surface) {
Expand Down Expand Up @@ -217,6 +219,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
#define RMLSDL_WINDOW_EVENTS_BEGIN
#define RMLSDL_WINDOW_EVENTS_END
auto GetKey = [](const SDL_Event& event) { return event.key.key; };
auto GetDisplayScale = []() { return SDL_GetWindowDisplayScale(data->window); };
constexpr auto event_quit = SDL_EVENT_QUIT;
constexpr auto event_key_down = SDL_EVENT_KEY_DOWN;
constexpr auto event_window_size_changed = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
Expand All @@ -232,6 +235,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
} \
break;
auto GetKey = [](const SDL_Event& event) { return event.key.keysym.sym; };
auto GetDisplayScale = []() { return 1.f; };
constexpr auto event_quit = SDL_QUIT;
constexpr auto event_key_down = SDL_KEYDOWN;
constexpr auto event_window_size_changed = SDL_WINDOWEVENT_SIZE_CHANGED;
Expand Down Expand Up @@ -263,13 +267,13 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
propagate_event = false;
const Rml::Input::KeyIdentifier key = RmlSDL::ConvertKey(GetKey(ev));
const int key_modifier = RmlSDL::GetKeyModifierState();
const float native_dp_ratio = 1.f;
const float native_dp_ratio = GetDisplayScale();

// See if we have any global shortcuts that take priority over the context.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, true))
break;
// Otherwise, hand the event over to the context by calling the input handler as normal.
if (!RmlSDL::InputEventHandler(context, ev))
if (!RmlSDL::InputEventHandler(context, data->window, ev))
break;
// The key was not consumed by the context either, try keyboard shortcuts of lower priority.
if (key_down_callback && !key_down_callback(context, key, key_modifier, native_dp_ratio, false))
Expand All @@ -292,7 +296,7 @@ bool Backend::ProcessEvents(Rml::Context* context, KeyDownCallback key_down_call
}

if (propagate_event)
RmlSDL::InputEventHandler(context, ev);
RmlSDL::InputEventHandler(context, data->window, ev);

has_event = SDL_PollEvent(&ev);
}
Expand Down
12 changes: 11 additions & 1 deletion Backends/RmlUi_Platform_SDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void SystemInterface_SDL::DeactivateKeyboard()
}
}

bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev)
bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Window* window, SDL_Event& ev)
{
#if SDL_MAJOR_VERSION >= 3
#define RMLSDL_WINDOW_EVENTS_BEGIN
Expand All @@ -165,6 +165,7 @@ bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev)
constexpr auto rmlsdl_true = true;
constexpr auto rmlsdl_false = false;
#else
(void)window;
#define RMLSDL_WINDOW_EVENTS_BEGIN \
case SDL_WINDOWEVENT: \
{ \
Expand Down Expand Up @@ -246,6 +247,15 @@ bool RmlSDL::InputEventHandler(Rml::Context* context, SDL_Event& ev)
}
break;

#if SDL_MAJOR_VERSION >= 3
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
{
const float display_scale = SDL_GetWindowDisplayScale(window);
context->SetDensityIndependentPixelRatio(display_scale);
}
break;
#endif

RMLSDL_WINDOW_EVENTS_END

default: break;
Expand Down
2 changes: 1 addition & 1 deletion Backends/RmlUi_Platform_SDL.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace RmlSDL {

// Applies input on the context based on the given SDL event.
// @return True if the event is still propagating, false if it was handled by the context.
bool InputEventHandler(Rml::Context* context, SDL_Event& ev);
bool InputEventHandler(Rml::Context* context, SDL_Window* window, SDL_Event& ev);

// Converts the SDL key to RmlUi key.
Rml::Input::KeyIdentifier ConvertKey(int sdl_key);
Expand Down
18 changes: 17 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ The font face will be inherited from the element it is being applied to. However

- Fix incorrect clipping when using multiple contexts of different dimensions. #677 #680 (thanks @s1sw)

### Backends

- Update SFML backend to support SFML 3, in addition to the existing SFML 2 support.
- By default, SFML 3 is preferred before SFML 2 during CMake configuration. To override the automatic selection, set the CMake variable `RMLUI_SFML_VERSION_MAJOR` to the desired version (2 or 3).
- Update SDL backends to support SDL 3, in addition to the existing SDL 2 support.
- By default, SDL 3 is preferred before SDL 2 during CMake configuration. To override the automatic selection, set the CMake variable `RMLUI_SDL_VERSION_MAJOR` to the desired version (2 or 3).
- SDL 3-specific improvements:
- Enable high DPI support.
- Enable positioning of the input method editor (IME) to the text cursor.
- Improvements to both SDL 2 and SDL 3:
- Keyboard is activated and deactivated when focusing text input fields.
- Text input events are only submitted when text input fields are focused.
- `SDL_GL2`-specific improvements:
- GLEW is no longer required, and no longer linked to.
- Use OpenGL directly instead of the SDL renderer, just like the `SDL_GL3` renderer.

### Plugins

- Log warnings when SVG or Lottie files cannot be rendered. #687
Expand Down Expand Up @@ -142,7 +158,7 @@ The font face will be inherited from the element it is being applied to. However
- They now take the new `RenderBox` class as input. The `Element::GetRenderBox` method can be used to construct it.
- Changed `ComputedValues::border_radius` to return an array instead of `Vector4f`.
- `Rml::ReleaseMemoryPools` is no longer exposed publicly. This function is automatically called during shutdown and should not be used manually.

- SDL backends: The SDL platform's `InputEventHandler` function now takes an additional parameter `window`.

## RmlUi 6.0

Expand Down
Loading

0 comments on commit 56d1a21

Please sign in to comment.