mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 06:15:04 +00:00
Fix #9993: Handle DPI changes on macOS and Windows
This commit is contained in:
parent
bda602f4b0
commit
45d98f689a
@ -10,6 +10,7 @@
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
|
34
src/gfx.cpp
34
src/gfx.cpp
@ -17,10 +17,12 @@
|
||||
#include "settings_type.h"
|
||||
#include "network/network.h"
|
||||
#include "network/network_func.h"
|
||||
#include "window_gui.h"
|
||||
#include "window_func.h"
|
||||
#include "newgrf_debug.h"
|
||||
#include "thread.h"
|
||||
#include "core/backup_type.hpp"
|
||||
#include "viewport_func.h"
|
||||
|
||||
#include "table/palettes.h"
|
||||
#include "table/string_colours.h"
|
||||
@ -2042,6 +2044,38 @@ void UpdateGUIZoom()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested.
|
||||
* @returns true when the zoom level has changed, caller must call ReInitAllWindows(true)
|
||||
* after resizing the application's window/buffer.
|
||||
*/
|
||||
bool AdjustGUIZoom()
|
||||
{
|
||||
auto old_zoom = _gui_zoom;
|
||||
UpdateGUIZoom();
|
||||
if (old_zoom == _gui_zoom) return false;
|
||||
GfxClearSpriteCache();
|
||||
VideoDriver::GetInstance()->ClearSystemSprites();
|
||||
ClearFontCache();
|
||||
GfxClearSpriteCache();
|
||||
UpdateAllVirtCoords();
|
||||
|
||||
/* Adjust all window sizes to match the new zoom level, so that they don't appear
|
||||
to move around when the application is moved to a screen with different DPI. */
|
||||
auto zoom_shift = old_zoom - _gui_zoom;
|
||||
for (Window *w : Window::Iterate()) {
|
||||
w->left = AdjustByZoom(w->left, zoom_shift);
|
||||
w->top = AdjustByZoom(w->top, zoom_shift);
|
||||
w->width = AdjustByZoom(w->width, zoom_shift);
|
||||
w->height = AdjustByZoom(w->height, zoom_shift);
|
||||
if (w->viewport != nullptr) {
|
||||
w->viewport->zoom = Clamp(ZoomLevel(w->viewport->zoom - zoom_shift), _settings_client.gui.zoom_min, _settings_client.gui.zoom_max);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChangeGameSpeed(bool enable_fast_forward)
|
||||
{
|
||||
if (enable_fast_forward) {
|
||||
|
@ -80,6 +80,7 @@ void DrawMouseCursor();
|
||||
void ScreenSizeChanged();
|
||||
void GameSizeChanged();
|
||||
void UpdateGUIZoom();
|
||||
bool AdjustGUIZoom();
|
||||
void UndrawMouseCursor();
|
||||
|
||||
/** Size of the buffer used for drawing strings. */
|
||||
|
@ -1269,8 +1269,12 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel
|
||||
/** Screen the window is on changed. */
|
||||
- (void)windowDidChangeBackingProperties:(NSNotification *)notification
|
||||
{
|
||||
bool did_adjust = AdjustGUIZoom();
|
||||
|
||||
/* Reallocate screen buffer if necessary. */
|
||||
driver->AllocateBackingStore();
|
||||
|
||||
if (did_adjust) ReInitAllWindows(true);
|
||||
}
|
||||
|
||||
/** Presentation options to use for full screen mode. */
|
||||
|
@ -38,6 +38,10 @@
|
||||
#define PM_QS_INPUT 0x20000
|
||||
#endif
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif
|
||||
|
||||
bool _window_maximize;
|
||||
static Dimension _bck_resolution;
|
||||
DWORD _imm_props;
|
||||
@ -670,6 +674,24 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DPICHANGED: {
|
||||
auto did_adjust = AdjustGUIZoom();
|
||||
|
||||
/* Resize the window to match the new DPI setting. */
|
||||
RECT *prcNewWindow = (RECT *)lParam;
|
||||
SetWindowPos(hwnd,
|
||||
NULL,
|
||||
prcNewWindow->left,
|
||||
prcNewWindow->top,
|
||||
prcNewWindow->right - prcNewWindow->left,
|
||||
prcNewWindow->bottom - prcNewWindow->top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
if (did_adjust) ReInitAllWindows(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* needed for wheel */
|
||||
#if !defined(WM_MOUSEWHEEL)
|
||||
# define WM_MOUSEWHEEL 0x020A
|
||||
|
@ -3343,6 +3343,13 @@ void HideVitalWindows()
|
||||
CloseWindowById(WC_STATUS_BAR, 0);
|
||||
}
|
||||
|
||||
void ReInitWindow(Window *w, bool zoom_changed)
|
||||
{
|
||||
if (w == nullptr) return;
|
||||
if (zoom_changed) w->nested_root->AdjustPaddingForZoom();
|
||||
w->ReInit();
|
||||
}
|
||||
|
||||
/** Re-initialize all windows. */
|
||||
void ReInitAllWindows(bool zoom_changed)
|
||||
{
|
||||
@ -3352,9 +3359,13 @@ void ReInitAllWindows(bool zoom_changed)
|
||||
extern void InitDepotWindowBlockSizes();
|
||||
InitDepotWindowBlockSizes();
|
||||
|
||||
/* When _gui_zoom has changed, we need to resize toolbar and statusbar first,
|
||||
* so EnsureVisibleCaption uses the updated size information. */
|
||||
ReInitWindow(FindWindowById(WC_MAIN_TOOLBAR, 0), zoom_changed);
|
||||
ReInitWindow(FindWindowById(WC_STATUS_BAR, 0), zoom_changed);
|
||||
for (Window *w : Window::Iterate()) {
|
||||
if (zoom_changed) w->nested_root->AdjustPaddingForZoom();
|
||||
w->ReInit();
|
||||
if (w->window_class == WC_MAIN_TOOLBAR || w->window_class == WC_STATUS_BAR) continue;
|
||||
ReInitWindow(w, zoom_changed);
|
||||
}
|
||||
|
||||
void NetworkReInitChatBoxSize();
|
||||
|
@ -36,6 +36,17 @@ static inline int UnScaleByZoom(int value, ZoomLevel zoom)
|
||||
return (value + (1 << zoom) - 1) >> zoom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust by zoom level; zoom < 0 shifts right, zoom >= 0 shifts left
|
||||
* @param value value to shift
|
||||
* @param zoom zoom level to shift to
|
||||
* @return shifted value
|
||||
*/
|
||||
static inline int AdjustByZoom(int value, int zoom)
|
||||
{
|
||||
return zoom < 0 ? UnScaleByZoom(value, ZoomLevel(-zoom)) : ScaleByZoom(value, ZoomLevel(zoom));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL)
|
||||
* @param value value to shift
|
||||
|
Loading…
Reference in New Issue
Block a user