feat: screenshot app improvement, WIndow Server supports full-screen overlay, Disks app UI improvements

This commit is contained in:
2026-05-10 10:45:05 +02:00
parent 60ee905552
commit dcdbcac1e0
29 changed files with 1483 additions and 395 deletions
+156 -87
View File
@@ -94,6 +94,47 @@ static void handle_lock_keyboard(DesktopState* ds, const Montauk::KeyEvent& key)
}
}
static void forward_external_mouse(gui::Window* win,
const gui::MouseEvent& ev,
int mx,
int my,
uint8_t buttons,
uint8_t prev) {
gui::Rect cr = desktop_content_rect(win);
Montauk::WinEvent wev;
montauk::memset(&wev, 0, sizeof(wev));
wev.type = 1; // mouse
wev.mouse.x = mx - cr.x;
wev.mouse.y = my - cr.y;
wev.mouse.scroll = ev.scroll;
wev.mouse.buttons = buttons;
wev.mouse.prev_buttons = prev;
montauk::win_sendevent(win->ext_win_id, &wev);
}
static bool route_fullscreen_external_mouse(gui::DesktopState* ds,
const gui::MouseEvent& ev,
int mx,
int my,
uint8_t buttons,
uint8_t prev) {
for (int i = ds->window_count - 1; i >= 0; i--) {
gui::Window* win = &ds->windows[i];
if (win->state == gui::WIN_MINIMIZED || win->state == gui::WIN_CLOSED)
continue;
if (!desktop_window_fullscreen(win))
return false;
if (i != ds->window_count - 1) {
gui::desktop_raise_window(ds, i);
win = &ds->windows[ds->window_count - 1];
}
forward_external_mouse(win, ev, mx, my, buttons, prev);
return true;
}
return false;
}
// ============================================================================
// Desktop Mouse Handling
// ============================================================================
@@ -104,11 +145,6 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
return;
}
if (ds->launcher_open) {
desktop_handle_launcher_mouse(ds);
return;
}
int mx = ds->mouse.x;
int my = ds->mouse.y;
uint8_t buttons = ds->mouse.buttons;
@@ -125,6 +161,19 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
ev.prev_buttons = prev;
ev.scroll = ds->mouse.scrollDelta;
if (route_fullscreen_external_mouse(ds, ev, mx, my, buttons, prev)) {
ds->app_menu_open = false;
ds->ctx_menu_open = false;
ds->vol_popup_open = false;
ds->net_popup_open = false;
return;
}
if (ds->launcher_open) {
desktop_handle_launcher_mouse(ds);
return;
}
// Handle context menu clicks
if (ds->ctx_menu_open) {
if (left_pressed) {
@@ -183,7 +232,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
win->frame = {0, PANEL_HEIGHT, ds->screen_w / 2, ds->screen_h - PANEL_HEIGHT};
win->state = WIN_MAXIMIZED;
if (!win->external) {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
if (cr.w != win->content_w || cr.h != win->content_h) {
if (win->content) montauk::free(win->content);
win->content_w = cr.w;
@@ -192,7 +241,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
montauk::memset(win->content, 0xFF, cr.w * cr.h * 4);
}
} else {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
Montauk::WinEvent rev;
montauk::memset(&rev, 0, sizeof(rev));
rev.type = 2;
@@ -205,7 +254,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
win->frame = {ds->screen_w / 2, PANEL_HEIGHT, ds->screen_w / 2, ds->screen_h - PANEL_HEIGHT};
win->state = WIN_MAXIMIZED;
if (!win->external) {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
if (cr.w != win->content_w || cr.h != win->content_h) {
if (win->content) montauk::free(win->content);
win->content_w = cr.w;
@@ -214,7 +263,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
montauk::memset(win->content, 0xFF, cr.w * cr.h * 4);
}
} else {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
Montauk::WinEvent rev;
montauk::memset(&rev, 0, sizeof(rev));
rev.type = 2;
@@ -271,7 +320,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
win->resizing = false;
// Reallocate content buffer if dimensions changed (skip for external)
if (!win->external) {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
if (cr.w != win->content_w || cr.h != win->content_h) {
if (win->content) montauk::free(win->content);
win->content_w = cr.w;
@@ -281,7 +330,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
}
win->dirty = true;
} else {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
Montauk::WinEvent rev;
montauk::memset(&rev, 0, sizeof(rev));
rev.type = 2;
@@ -505,92 +554,94 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
Window* win = &ds->windows[i];
if (win->state == WIN_MINIMIZED || win->state == WIN_CLOSED) continue;
// Check close button
Rect close_r = win->close_btn_rect();
if (close_r.contains(mx, my)) {
desktop_close_window(ds, i);
return;
}
if (!desktop_window_fullscreen(win)) {
// Check close button
Rect close_r = win->close_btn_rect();
if (close_r.contains(mx, my)) {
desktop_close_window(ds, i);
return;
}
// Check minimize button
Rect min_r = win->min_btn_rect();
if (min_r.contains(mx, my)) {
win->state = WIN_MINIMIZED;
if (ds->focused_window == i) {
ds->focused_window = -1;
for (int j = ds->window_count - 1; j >= 0; j--) {
if (ds->windows[j].state == WIN_NORMAL || ds->windows[j].state == WIN_MAXIMIZED) {
ds->focused_window = j;
ds->windows[j].focused = true;
break;
// Check minimize button
Rect min_r = win->min_btn_rect();
if (min_r.contains(mx, my)) {
win->state = WIN_MINIMIZED;
if (ds->focused_window == i) {
ds->focused_window = -1;
for (int j = ds->window_count - 1; j >= 0; j--) {
if (ds->windows[j].state == WIN_NORMAL || ds->windows[j].state == WIN_MAXIMIZED) {
ds->focused_window = j;
ds->windows[j].focused = true;
break;
}
}
}
return;
}
return;
}
// Check maximize button
Rect max_r = win->max_btn_rect();
if (max_r.contains(mx, my)) {
if (win->state == WIN_MAXIMIZED) {
win->frame = win->saved_frame;
win->state = WIN_NORMAL;
} else {
win->saved_frame = win->frame;
win->frame = {0, PANEL_HEIGHT, ds->screen_w, ds->screen_h - PANEL_HEIGHT};
win->state = WIN_MAXIMIZED;
}
// Reallocate content buffer for local windows only
if (!win->external) {
Rect cr = win->content_rect();
if (cr.w != win->content_w || cr.h != win->content_h) {
if (win->content) montauk::free(win->content);
win->content_w = cr.w;
win->content_h = cr.h;
win->content = (uint32_t*)montauk::alloc(cr.w * cr.h * 4);
montauk::memset(win->content, 0xFF, cr.w * cr.h * 4);
// Check maximize button
Rect max_r = win->max_btn_rect();
if (max_r.contains(mx, my)) {
if (win->state == WIN_MAXIMIZED) {
win->frame = win->saved_frame;
win->state = WIN_NORMAL;
} else {
win->saved_frame = win->frame;
win->frame = {0, PANEL_HEIGHT, ds->screen_w, ds->screen_h - PANEL_HEIGHT};
win->state = WIN_MAXIMIZED;
}
} else {
Rect cr = win->content_rect();
Montauk::WinEvent rev;
montauk::memset(&rev, 0, sizeof(rev));
rev.type = 2;
rev.resize.w = cr.w;
rev.resize.h = cr.h;
montauk::win_sendevent(win->ext_win_id, &rev);
// Reallocate content buffer for local windows only
if (!win->external) {
Rect cr = desktop_content_rect(win);
if (cr.w != win->content_w || cr.h != win->content_h) {
if (win->content) montauk::free(win->content);
win->content_w = cr.w;
win->content_h = cr.h;
win->content = (uint32_t*)montauk::alloc(cr.w * cr.h * 4);
montauk::memset(win->content, 0xFF, cr.w * cr.h * 4);
}
} else {
Rect cr = desktop_content_rect(win);
Montauk::WinEvent rev;
montauk::memset(&rev, 0, sizeof(rev));
rev.type = 2;
rev.resize.w = cr.w;
rev.resize.h = cr.h;
montauk::win_sendevent(win->ext_win_id, &rev);
}
desktop_raise_window(ds, i);
return;
}
desktop_raise_window(ds, i);
return;
}
// Check resize edges (before titlebar drag, so corner grabs work)
if (win->state != WIN_MAXIMIZED) {
ResizeEdge edge = hit_test_resize_edge(win->frame, mx, my);
if (edge != RESIZE_NONE) {
// Check resize edges (before titlebar drag, so corner grabs work)
if (win->state != WIN_MAXIMIZED) {
ResizeEdge edge = hit_test_resize_edge(win->frame, mx, my);
if (edge != RESIZE_NONE) {
desktop_raise_window(ds, i);
int new_idx = ds->window_count - 1;
ds->windows[new_idx].resizing = true;
ds->windows[new_idx].resize_edge = edge;
ds->windows[new_idx].resize_start_frame = ds->windows[new_idx].frame;
ds->windows[new_idx].resize_start_mx = mx;
ds->windows[new_idx].resize_start_my = my;
return;
}
}
// Check titlebar (start drag)
Rect tb = win->titlebar_rect();
if (tb.contains(mx, my)) {
desktop_raise_window(ds, i);
int new_idx = ds->window_count - 1;
ds->windows[new_idx].resizing = true;
ds->windows[new_idx].resize_edge = edge;
ds->windows[new_idx].resize_start_frame = ds->windows[new_idx].frame;
ds->windows[new_idx].resize_start_mx = mx;
ds->windows[new_idx].resize_start_my = my;
ds->windows[new_idx].dragging = true;
ds->windows[new_idx].drag_offset_x = mx - ds->windows[new_idx].frame.x;
ds->windows[new_idx].drag_offset_y = my - ds->windows[new_idx].frame.y;
return;
}
}
// Check titlebar (start drag)
Rect tb = win->titlebar_rect();
if (tb.contains(mx, my)) {
desktop_raise_window(ds, i);
int new_idx = ds->window_count - 1;
ds->windows[new_idx].dragging = true;
ds->windows[new_idx].drag_offset_x = mx - ds->windows[new_idx].frame.x;
ds->windows[new_idx].drag_offset_y = my - ds->windows[new_idx].frame.y;
return;
}
// Check content area
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
if (cr.contains(mx, my)) {
desktop_raise_window(ds, i);
int new_idx = ds->window_count - 1;
@@ -630,7 +681,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
if (!left_pressed && ds->focused_window >= 0) {
Window* win = &ds->windows[ds->focused_window];
if (win->state != WIN_MINIMIZED && win->state != WIN_CLOSED) {
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
// Forward if mouse is over content (hover/move) or button is held/released (drag continuity)
if (cr.contains(mx, my) || left_held || left_released) {
if (win->external) {
@@ -655,7 +706,7 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
// Handle scroll events on focused window
if (ev.scroll != 0 && ds->focused_window >= 0) {
Window* win = &ds->windows[ds->focused_window];
Rect cr = win->content_rect();
Rect cr = desktop_content_rect(win);
if (cr.contains(mx, my)) {
if (win->external) {
Montauk::WinEvent wev;
@@ -696,12 +747,30 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
}
void gui::desktop_handle_keyboard(DesktopState* ds, const Montauk::KeyEvent& key) {
if (desktop_handle_launcher_keyboard(ds, key)) {
if (ds->screen_locked) {
handle_lock_keyboard(ds, key);
return;
}
if (ds->screen_locked) {
handle_lock_keyboard(ds, key);
for (int i = ds->window_count - 1; i >= 0; i--) {
Window* win = &ds->windows[i];
if (win->state == WIN_MINIMIZED || win->state == WIN_CLOSED)
continue;
if (!desktop_window_fullscreen(win))
break;
Montauk::WinEvent ev;
montauk::memset(&ev, 0, sizeof(ev));
ev.type = 0; // key
ev.key = key;
montauk::win_sendevent(win->ext_win_id, &ev);
ds->launcher_open = false;
ds->app_menu_open = false;
ds->ctx_menu_open = false;
return;
}
if (desktop_handle_launcher_keyboard(ds, key)) {
return;
}