better scaling of window borders

This commit is contained in:
nakst 2021-09-07 19:10:01 +01:00
parent 10b259ca66
commit 55edbd26be
7 changed files with 65 additions and 78 deletions

View File

@ -1887,10 +1887,13 @@ void DesktopSetup() {
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, desktop.wallpaperWindow->handle, (uintptr_t) &screen, 0, ES_WINDOW_PROPERTY_OPAQUE_BOUNDS);
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, desktop.wallpaperWindow->handle,
ES_WINDOW_SOLID_TRUE | ES_WINDOW_SOLID_NO_BRING_TO_FRONT, 0, ES_WINDOW_PROPERTY_SOLID);
desktop.wallpaperWindow->windowWidth = Width(screen);
desktop.wallpaperWindow->windowHeight = Height(screen);
desktop.wallpaperWindow->doNotPaint = true;
EsThreadCreate(WallpaperLoad, nullptr, 0);
if ((int32_t) desktop.wallpaperWindow->windowWidth != Width(screen) || (int32_t) desktop.wallpaperWindow->windowHeight != Height(screen)) {
desktop.wallpaperWindow->windowWidth = Width(screen);
desktop.wallpaperWindow->windowHeight = Height(screen);
EsThreadCreate(WallpaperLoad, nullptr, 0);
}
}
if (desktop.installationState == INSTALLATION_STATE_NONE) {

View File

@ -17,8 +17,8 @@
// Behaviour of activation clicks. --> Only ignore activation clicks from menus.
// Behaviour of the scroll wheel with regards to focused/hovered elements --> Scroll the hovered element only.
#define WINDOW_INSET ((int) api.systemConstants[ES_SYSTEM_CONSTANT_WINDOW_INSET])
#define CONTAINER_TAB_BAND_HEIGHT ((int) api.systemConstants[ES_SYSTEM_CONSTANT_CONTAINER_TAB_BAND_HEIGHT])
#define WINDOW_INSET ((int) (19 * theming.scale))
#define CONTAINER_TAB_BAND_HEIGHT ((int) (33 * theming.scale))
#define BORDER_THICKNESS ((int) (9 * theming.scale))
// #define TRACE_LAYOUT
@ -764,6 +764,11 @@ int ProcessRootMessage(EsElement *element, EsMessage *message) {
if (window->windowStyle == ES_WINDOW_CONTAINER) {
if (message->type == ES_MSG_LAYOUT) {
EsElementMove(window->GetChild(0), WINDOW_INSET, WINDOW_INSET, bounds.r - WINDOW_INSET * 2, CONTAINER_TAB_BAND_HEIGHT);
} else if (message->type == ES_MSG_UI_SCALE_CHANGED) {
// This message is also sent when the window is created.
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, ES_WINDOW_SOLID_TRUE, 10 * theming.scale, ES_WINDOW_PROPERTY_SOLID);
EsRectangle embedInsets = ES_RECT_4(WINDOW_INSET, WINDOW_INSET, WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT, WINDOW_INSET);
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, (uintptr_t) &embedInsets, 0, ES_WINDOW_PROPERTY_EMBED_INSETS);
} else {
response = ProcessWindowBorderMessage(window, message, bounds, WINDOW_INSET - BORDER_THICKNESS, WINDOW_INSET);
}
@ -886,9 +891,10 @@ EsWindow *EsWindowCreate(EsInstance *instance, EsWindowStyle style) {
cascadeX += cascadeOffset, cascadeY += cascadeOffset;
EsSyscall(ES_SYSCALL_WINDOW_MOVE, window->handle, (uintptr_t) &bounds, 0, ES_FLAGS_DEFAULT);
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, 0, 0, ES_WINDOW_PROPERTY_FOCUSED);
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, ES_WINDOW_SOLID_TRUE, 10, ES_WINDOW_PROPERTY_SOLID);
window->mainPanel = EsPanelCreate(window, ES_ELEMENT_NON_CLIENT | ES_CELL_FILL, ES_STYLE_PANEL_CONTAINER_WINDOW_ROOT);
window->SetStyle(ES_STYLE_CONTAINER_WINDOW_ACTIVE);
EsMessage m = { .type = ES_MSG_UI_SCALE_CHANGED };
EsMessageSend(window, &m);
} else if (style == ES_WINDOW_INSPECTOR) {
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, ES_WINDOW_SOLID_TRUE, 0, ES_WINDOW_PROPERTY_SOLID);
window->SetStyle(ES_STYLE_PANEL_INSPECTOR_WINDOW_ROOT);
@ -6819,11 +6825,10 @@ void UIProcessWindowManagerMessage(EsWindow *window, EsMessage *message, Process
window->height = window->windowHeight = message->windowResized.content.b;
if (window->windowStyle == ES_WINDOW_CONTAINER) {
EsRectangle opaqueBounds = ES_RECT_4(WINDOW_INSET, window->windowWidth - WINDOW_INSET,
WINDOW_INSET, window->windowHeight - WINDOW_INSET);
EsRectangle opaqueBounds = ES_RECT_4(WINDOW_INSET, window->windowWidth - WINDOW_INSET, WINDOW_INSET, window->windowHeight - WINDOW_INSET);
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, (uintptr_t) &opaqueBounds, 0, ES_WINDOW_PROPERTY_OPAQUE_BOUNDS);
} else if (window->windowStyle == ES_WINDOW_INSPECTOR) {
EsRectangle opaqueBounds = ES_RECT_4(0, window->windowWidth, 0, window->windowHeight);
EsRectangle opaqueBounds = ES_RECT_2S(window->windowWidth, window->windowHeight);
EsSyscall(ES_SYSCALL_WINDOW_SET_PROPERTY, window->handle, (uintptr_t) &opaqueBounds, 0, ES_WINDOW_PROPERTY_OPAQUE_BOUNDS);
}

View File

@ -332,10 +332,7 @@ define ES_ERROR_CANCELLED (-73)
define ES_SYSTEM_CONSTANT_TIME_STAMP_UNITS_PER_MICROSECOND (0)
define ES_SYSTEM_CONSTANT_OPTIMAL_WORK_QUEUE_THREAD_COUNT (1)
define ES_SYSTEM_CONSTANT_WINDOW_INSET (2)
define ES_SYSTEM_CONSTANT_CONTAINER_TAB_BAND_HEIGHT (3)
define ES_SYSTEM_CONSTANT_UI_SCALE (4)
define ES_SYSTEM_CONSTANT_COUNT (5)
define ES_SYSTEM_CONSTANT_COUNT (2)
define ES_INVALID_HANDLE ((EsHandle) (0))
define ES_CURRENT_THREAD ((EsHandle) (0x10))
@ -720,6 +717,7 @@ define ES_WINDOW_PROPERTY_ALPHA (0x04)
define ES_WINDOW_PROPERTY_FOCUSED (0x05)
define ES_WINDOW_PROPERTY_MATERIAL (0x06)
define ES_WINDOW_PROPERTY_EMBED (0x07)
define ES_WINDOW_PROPERTY_EMBED_INSETS (0x08)
define ES_WINDOW_PROPERTY_OBJECT (0x81) // Embedded window properties.
define ES_WINDOW_PROPERTY_EMBED_OWNER (0x82)
define ES_WINDOW_PROPERTY_RESIZE_CLEAR_COLOR (0x83)

View File

@ -256,7 +256,7 @@ void SettingsCheckboxCommand(EsInstance *_instance, EsElement *element, EsComman
EsMutexAcquire(&api.systemConfigurationMutex);
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(control->cConfigurationSection, -1, true);
bool oldValue;
bool oldValue = false;
if (group) {
EsSystemConfigurationItem *item = SystemConfigurationGetItem(group, control->cConfigurationKey, -1, true);
@ -382,7 +382,7 @@ int SettingsSliderMessage(EsElement *element, EsMessage *message) {
EsMutexAcquire(&api.systemConfigurationMutex);
EsSystemConfigurationGroup *group = SystemConfigurationGetGroup(control->cConfigurationSection, -1, true);
int32_t oldValue;
int32_t oldValue = 0;
int32_t newValue = LinearMap(0, 1, control->minimumValue, control->maximumValue, EsSliderGetValue(slider));
if (group) {

View File

@ -425,6 +425,11 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_PROPERTY) {
KMutexAcquire(&windowManager.mutex);
window->SetEmbed(embed);
KMutexRelease(&windowManager.mutex);
} else if (property == ES_WINDOW_PROPERTY_EMBED_INSETS) {
KMutexAcquire(&windowManager.mutex);
SYSCALL_READ(&window->embedInsets, argument1, sizeof(EsRectangle));
window->ResizeEmbed();
KMutexRelease(&windowManager.mutex);
} else if (property == ES_WINDOW_PROPERTY_OBJECT) {
if (embed->owner != currentProcess) {
// TODO Permissions.
@ -434,17 +439,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_PROPERTY) {
__sync_synchronize();
KMutexAcquire(&windowManager.mutex);
if (embed->container) {
EsMessage message;
EsMemoryZero(&message, sizeof(EsMessage));
message.type = ES_MSG_WINDOW_RESIZED;
int embedWidth = embed->container->width - WINDOW_INSET * 2;
int embedHeight = embed->container->height - WINDOW_INSET * 2 - CONTAINER_TAB_BAND_HEIGHT;
message.windowResized.content = ES_RECT_4(0, embedWidth, 0, embedHeight);
embed->owner->messageQueue.SendMessage((void *) argument2, &message);
}
if (embed->container) embed->container->ResizeEmbed();
KMutexRelease(&windowManager.mutex);
} else if (property == ES_WINDOW_PROPERTY_EMBED_OWNER) {
Process *process;
@ -494,13 +489,14 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
bool isEmbed = _window.type == KERNEL_OBJECT_EMBEDDED_WINDOW;
Window *window = isEmbed ? ((EmbeddedWindow *) _window.object)->container : ((Window *) _window.object);
Surface *surface = &window->surface;
EsRectangle insets = window->embedInsets;
if (!window || (isEmbed && currentProcess != ((EmbeddedWindow *) _window.object)->owner)) {
SYSCALL_RETURN(ES_SUCCESS, false);
}
if (isEmbed) {
region = Translate(region, WINDOW_INSET, WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT);
region = Translate(region, insets.l, insets.t);
}
if (argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL || argument3 == WINDOW_SET_BITS_SCROLL_HORIZONTAL) {
@ -570,12 +566,12 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
+ stride * (subRegion.t - clippedRegion.t) + 4 * (subRegion.l - clippedRegion.l), stride, subRegion); } }
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
SET_BITS_REGION(0, window->width, 0, CONTAINER_TAB_BAND_HEIGHT + WINDOW_INSET);
SET_BITS_REGION(0, WINDOW_INSET, CONTAINER_TAB_BAND_HEIGHT + WINDOW_INSET, window->height - WINDOW_INSET);
SET_BITS_REGION(window->width - WINDOW_INSET, window->width, CONTAINER_TAB_BAND_HEIGHT + WINDOW_INSET, window->height - WINDOW_INSET);
SET_BITS_REGION(0, window->width, window->height - WINDOW_INSET, window->height);
SET_BITS_REGION(0, window->width, 0, insets.t);
SET_BITS_REGION(0, insets.l, insets.t, window->height - insets.b);
SET_BITS_REGION(window->width - insets.r, window->width, insets.t, window->height - insets.b);
SET_BITS_REGION(0, window->width, window->height - insets.b, window->height);
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
SET_BITS_REGION(WINDOW_INSET, window->width - WINDOW_INSET, WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT, window->height - WINDOW_INSET);
SET_BITS_REGION(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
} else {
SET_BITS_REGION(0, window->width, 0, window->height);
}
@ -1215,15 +1211,10 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_GET_BOUNDS) {
Window *window = embed->container;
if (window) {
rectangle.l = window->position.x + WINDOW_INSET;
rectangle.t = window->position.y + WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT;
rectangle.r = window->position.x + window->width - WINDOW_INSET;
rectangle.b = window->position.y + window->height - WINDOW_INSET;
} else {
rectangle.l = 0;
rectangle.t = 0;
rectangle.r = 0;
rectangle.b = 0;
rectangle.l = window->position.x + window->embedInsets.l;
rectangle.t = window->position.y + window->embedInsets.t;
rectangle.r = window->position.x + window->width - window->embedInsets.r;
rectangle.b = window->position.y + window->height - window->embedInsets.b;
}
}
@ -1430,9 +1421,6 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_SYSTEM_GET_CONSTANTS) {
uint64_t systemConstants[ES_SYSTEM_CONSTANT_COUNT];
EsMemoryZero(systemConstants, sizeof(systemConstants));
systemConstants[ES_SYSTEM_CONSTANT_TIME_STAMP_UNITS_PER_MICROSECOND] = timeStampTicksPerMs / 1000;
systemConstants[ES_SYSTEM_CONSTANT_WINDOW_INSET] = WINDOW_INSET;
systemConstants[ES_SYSTEM_CONSTANT_CONTAINER_TAB_BAND_HEIGHT] = CONTAINER_TAB_BAND_HEIGHT;
systemConstants[ES_SYSTEM_CONSTANT_UI_SCALE] = UI_SCALE;
systemConstants[ES_SYSTEM_CONSTANT_OPTIMAL_WORK_QUEUE_THREAD_COUNT] = scheduler.currentProcessorID; // TODO Update this as processors are added/removed.
SYSCALL_WRITE(argument0, systemConstants, sizeof(systemConstants));
SYSCALL_RETURN(ES_SUCCESS, false);

View File

@ -31,10 +31,11 @@ struct Window {
bool Move(EsRectangle newBounds, uint32_t flags);
void SetEmbed(EmbeddedWindow *window);
bool IsVisible();
void ResizeEmbed(); // Send a message to the embedded window telling it to resize.
// State:
EsWindowStyle style;
EsRectangle solidInsets;
EsRectangle solidInsets, embedInsets;
bool solid, noClickActivate, hidden, isMaximised, alwaysOnTop, hoveringOverEmbed, queuedScrollUpdate, activationClick, noBringToFront;
volatile bool closed;
EsMessage lastEmbedKeyboardMessage; // The most recent keyboard message sent to the embedded window.
@ -153,15 +154,6 @@ WindowManager windowManager;
void SendMessageToWindow(Window *window, EsMessage *message);
#ifdef TEST_HIGH_UI_SCALE
#define UI_SCALE TEST_HIGH_UI_SCALE
#else
#define UI_SCALE (100)
#endif
#define WINDOW_INSET (19 * UI_SCALE / 100)
#define CONTAINER_TAB_BAND_HEIGHT (33 * UI_SCALE / 100)
#else
bool Window::IsVisible() {
@ -185,22 +177,23 @@ void SendMessageToWindow(Window *window, EsMessage *message) {
}
if (message->type == ES_MSG_WINDOW_RESIZED) {
message->windowResized.content = ES_RECT_4(0, window->width, 0, window->height);
message->windowResized.content = ES_RECT_2S(window->width, window->height);
window->owner->messageQueue.SendMessage(window->apiWindow, message);
message->windowResized.content = ES_RECT_4(0, window->width - WINDOW_INSET * 2, 0, window->height - WINDOW_INSET * 2 - CONTAINER_TAB_BAND_HEIGHT);
message->windowResized.content = ES_RECT_2S(window->width - window->embedInsets.l - window->embedInsets.r,
window->height - window->embedInsets.t - window->embedInsets.b);
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
} else if (message->type == ES_MSG_WINDOW_DEACTIVATED || message->type == ES_MSG_WINDOW_ACTIVATED) {
window->owner->messageQueue.SendMessage(window->apiWindow, message);
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
} else if (message->type == ES_MSG_MOUSE_MOVED) {
EsRectangle embedRegion = ES_RECT_4(WINDOW_INSET, window->width - WINDOW_INSET, WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT, window->height - WINDOW_INSET);
EsRectangle embedRegion = ES_RECT_4(window->embedInsets.l, window->width - window->embedInsets.r,
window->embedInsets.t, window->height - window->embedInsets.b);
bool inEmbed = windowManager.pressedWindow ? window->hoveringOverEmbed
: EsRectangleContains(embedRegion, message->mouseMoved.newPositionX, message->mouseMoved.newPositionY);
if (inEmbed) {
message->mouseMoved.newPositionX -= WINDOW_INSET;
message->mouseMoved.newPositionY -= WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT;
message->mouseMoved.newPositionX -= window->embedInsets.l;
message->mouseMoved.newPositionY -= window->embedInsets.t;
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
@ -222,8 +215,8 @@ void SendMessageToWindow(Window *window, EsMessage *message) {
}
} else if (message->type >= ES_MSG_MOUSE_LEFT_DOWN && message->type <= ES_MSG_MOUSE_MIDDLE_UP) {
if (window->hoveringOverEmbed) {
message->mouseDown.positionX -= WINDOW_INSET;
message->mouseDown.positionY -= WINDOW_INSET + CONTAINER_TAB_BAND_HEIGHT;
message->mouseDown.positionX -= window->embedInsets.l;
message->mouseDown.positionY -= window->embedInsets.t;
if (!window->activationClick) {
window->embed->owner->messageQueue.SendMessage(window->embed->apiWindow, message);
@ -868,10 +861,7 @@ bool Window::Move(EsRectangle rectangle, uint32_t flags) {
}
if ((flags & ES_WINDOW_MOVE_DYNAMIC) && changedSize && style == ES_WINDOW_CONTAINER && !windowManager.resizeSlow) {
windowManager.Redraw(ES_POINT(position.x, position.y), WINDOW_INSET, height, nullptr);
windowManager.Redraw(ES_POINT(position.x + width - WINDOW_INSET, position.y), WINDOW_INSET, height, nullptr);
windowManager.Redraw(ES_POINT(position.x + WINDOW_INSET, position.y), width - WINDOW_INSET * 2, WINDOW_INSET, nullptr);
windowManager.Redraw(ES_POINT(position.x + WINDOW_INSET, position.y + height - WINDOW_INSET), width - WINDOW_INSET * 2, WINDOW_INSET, nullptr);
// Don't redraw anything yet.
} else {
windowManager.Redraw(position, width, height, nullptr);
}
@ -1152,6 +1142,16 @@ void EmbeddedWindow::SetEmbedOwner(Process *process) {
owner = process;
}
void Window::ResizeEmbed() {
KMutexAssertLocked(&windowManager.mutex);
if (!embed || !embed->apiWindow) return;
EsMessage message;
EsMemoryZero(&message, sizeof(EsMessage));
message.type = ES_MSG_WINDOW_RESIZED;
message.windowResized.content = ES_RECT_2S(width - embedInsets.l - embedInsets.r, height - embedInsets.t - embedInsets.b);
embed->owner->messageQueue.SendMessage(embed->apiWindow, &message);
}
void Window::SetEmbed(EmbeddedWindow *newEmbed) {
KMutexAssertLocked(&windowManager.mutex);
@ -1163,17 +1163,6 @@ void Window::SetEmbed(EmbeddedWindow *newEmbed) {
return;
}
if (newEmbed) {
newEmbed->container = this;
EsMessage message;
EsMemoryZero(&message, sizeof(EsMessage));
message.type = ES_MSG_WINDOW_RESIZED;
int embedWidth = width - WINDOW_INSET * 2;
int embedHeight = height - WINDOW_INSET * 2 - CONTAINER_TAB_BAND_HEIGHT;
message.windowResized.content = ES_RECT_4(0, embedWidth, 0, embedHeight);
newEmbed->owner->messageQueue.SendMessage(newEmbed->apiWindow, &message);
}
if (embed) {
if (embed->closed) {
KernelPanic("Window::SetEmbed - Previous embed %x was closed.\n");
@ -1193,6 +1182,11 @@ void Window::SetEmbed(EmbeddedWindow *newEmbed) {
}
embed = newEmbed;
if (embed) {
embed->container = this;
ResizeEmbed();
}
}
void WindowManager::StartEyedrop(uintptr_t object, Window *avoid, uint32_t cancelColor) {

View File

@ -282,7 +282,6 @@ Option options[] = {
{ "Flag.USE_SMP", OPTION_TYPE_BOOL, { .b = true } },
{ "Flag.BGA_RESOLUTION_WIDTH", OPTION_TYPE_STRING, { .s = "1600" } },
{ "Flag.BGA_RESOLUTION_HEIGHT", OPTION_TYPE_STRING, { .s = "900" } },
{ "Flag.TEST_HIGH_UI_SCALE", OPTION_TYPE_STRING, { .s = "100" } },
{ "Flag.VGA_TEXT_MODE", OPTION_TYPE_BOOL, { .b = false } },
{ "Flag.CHECK_FOR_NOT_RESPONDING", OPTION_TYPE_BOOL, { .b = true } },
{ "Flag._ALWAYS_USE_VBE", OPTION_TYPE_BOOL, { .b = false } },