import { ComboBox, ScrollView } from "std-widgets.slint"; import { FontAwesomeIcons, IconButton, PrimaryButton, ImGuiLineStyle, ImGuiFontStyle } from "common.slint"; export struct StreamTab { remote-id: string, title: string, connected: bool, } export struct FileTransferEntry { name: string, status: string, progress: float, speed: string, size: string, } export struct NetworkStatsRow { label: string, inbound: string, outbound: string, loss-rate: string, } export global StreamStrings { in-out property select-display: "Select Display"; in-out property send-shortcut: "Send Shortcut"; in-out property control-mouse: "Control Mouse"; in-out property release-mouse: "Release Mouse"; in-out property audio: "Audio Capture"; in-out property mute: "Mute"; in-out property select-file: "Select File to Send"; in-out property show-stats: "Show Net Traffic Stats"; in-out property hide-stats: "Hide Net Traffic Stats"; in-out property fullscreen: "Fullscreen"; in-out property exit-fullscreen: "Exit fullscreen"; in-out property disconnect: "Disconnect"; in-out property file-transfer: "File Transfer Progress"; in-out property expand-control: "Expand Control Bar"; in-out property collapse-control: "Collapse Control Bar"; in-out property stats-in: "In"; in-out property stats-out: "Out"; in-out property stats-loss-rate: "Loss Rate"; in-out property stats-resolution: "Res"; in-out property stats-connection-mode: "Mode"; } // The legacy ImGui control bar uses 24px buttons with Font Awesome rendered // at half of the 32px atlas size. Keep this local to the stream window: the // shared IconButton is intentionally larger and is used by the other windows. component ControlBarButton inherits Rectangle { in property icon; in property badge: ""; in property tooltip: ""; in property selected: false; in property slashed: false; in property icon-size: 16px; callback clicked; width: 24px; height: 24px; background: touch.pressed ? #0f87fa : touch.has-hover ? #4296fa : root.selected ? #4296fa : #4296fa66; border-radius: 3px; Text { text: root.icon; color: #24272d; font-family: "Font Awesome 6 Free"; font-weight: 900; font-size: root.icon-size; horizontal-alignment: center; vertical-alignment: center; } // Draw the selected display number over the center of the monitor glyph. if root.badge != "": Text { // Use the rendered badge size so one- and multi-digit IDs share the // exact horizontal and vertical center of the button. x: (parent.width - self.preferred-width) / 2 + 0.5px; y: (parent.height - self.preferred-height) / 2 - 0.5px; text: root.badge; color: black; font-size: 11px; } // Match the two offset diagonal strokes used by the ImGui mouse/audio // disabled state instead of covering the glyph with a full-width slash. if root.slashed: Rectangle { x: 11px; y: 0px; width: 2px; height: 24px; background: black; transform-rotation: -45deg; } if root.slashed: Rectangle { x: 9.5px; y: 1.5px; width: 2px; height: 24px; background: touch.has-hover ? #4296fa : #b3d5fd; transform-rotation: -45deg; } touch := TouchArea { clicked => { root.clicked(); } } } export component StreamWindow inherits Window { title: "CrossDesk"; preferred-width: 1280px; preferred-height: 720px + (root.custom-titlebar ? 32px : 0px); min-width: 640px; min-height: 360px + (root.custom-titlebar ? 32px : 0px); no-frame: root.custom-titlebar; background: root.custom-titlebar ? transparent : black; default-font-size: ImGuiFontStyle.base; in property custom-titlebar: false; in property window-active: true; in property window-maximized: false; in property <[StreamTab]> tabs; in-out property selected-tab: 0; in property frame; in property has-frame: false; in property status-text: ""; in property receiving-text: ""; in property <[string]> displays; in-out property selected-display: 0; in property mouse-control-enabled: true; in property audio-enabled: true; in property srtp-enabled: false; in property fullscreen-enabled: false; in property stats-visible: false; in property <[NetworkStatsRow]> stats-rows; in property stats-fps: "0"; in property stats-resolution: ""; in property stats-connection-mode: ""; in property file-transfer-visible: false; in property <[FileTransferEntry]> file-transfers; callback select-tab(int); callback reorder-tab(int, length, length); callback close-tab(string); callback switch-display(int); callback send-shortcut(string); callback toggle-mouse-control; callback toggle-audio; callback select-file; callback close-file-transfer; pure callback can-drop-file(data-transfer) -> bool; callback file-dropped(data-transfer); callback toggle-stats; callback toggle-fullscreen; callback disconnect; callback stream-title-drag(int, length, length); callback minimize-stream-window; callback toggle-maximize-stream-window; callback close-stream-window; callback pointer-input(PointerEventButton, PointerEventKind, length, length); callback scroll-input(length, length, length, length); callback key-input(string, bool, bool, bool, bool, bool); private property control-expanded: true; private property display-menu-open: false; private property shortcut-menu-open: false; private property control-docked-left: true; private property control-dragging: false; private property control-drag-x: 0px; // Start flush against the title/tab strip. This remains mutable so a // manually dragged control bar keeps its chosen vertical position. private property control-pos-y: 0px; private property control-press-x: 0px; private property control-press-y: 0px; private property dragging-tab: -1; private property titlebar-height: root.custom-titlebar && !root.fullscreen-enabled ? 32px : 0px; private property window-corner-radius: 12px; callback begin-control-drag(length, length); callback move-control-drag(length, length); callback end-control-drag; begin-control-drag(press-x, press-y) => { // Capture the snapped position before switching x to control-drag-x. // Otherwise a second press briefly restores the previous drag target // and makes a plain click move the control bar. let current-x = control.x; let current-y = control.y; root.control-drag-x = current-x; // Store the pointer offset in the control bar, while all following // pointer positions remain relative to the stationary video surface. root.control-press-x = press-x - current-x; root.control-press-y = press-y - current-y; root.display-menu-open = false; root.shortcut-menu-open = false; root.control-dragging = true; } move-control-drag(pointer-x, pointer-y) => { if root.control-dragging { root.control-drag-x = min(max(0px, pointer-x - root.control-press-x), video.width - control.width); root.control-pos-y = min(max(0px, pointer-y - root.control-press-y), video.height - control.height); } } end-control-drag() => { if root.control-dragging { root.control-docked-left = root.control-drag-x + control.width / 2 < video.width / 2; root.control-pos-y = min(max(0px, control.y), video.height - control.height); root.control-dragging = false; } } window-surface := Rectangle { width: root.width; height: root.height; background: black; border-radius: root.custom-titlebar && !root.fullscreen-enabled && !root.window-maximized ? root.window-corner-radius : 0px; clip: root.custom-titlebar && !root.fullscreen-enabled; if root.custom-titlebar && !root.fullscreen-enabled: Rectangle { x: 0px; y: 0px; width: parent.width; height: root.titlebar-height; background: #f6f5f4; z: 100; Text { x: 120px; width: parent.width - 240px; height: parent.height; text: "CrossDesk"; color: root.window-active ? #3d3d3d : #747474; font-size: 12px; font-weight: 600; horizontal-alignment: center; vertical-alignment: center; overflow: elide; } stream-title-drag-area := TouchArea { width: parent.width - 120px; property phase: self.pressed ? 1 : 0; changed phase => { root.stream-title-drag(phase, self.mouse-x, self.mouse-y); } moved => { if (self.pressed) { root.stream-title-drag(2, self.mouse-x, self.mouse-y); } } double-clicked => { root.toggle-maximize-stream-window(); } } stream-minimize-button := Rectangle { x: parent.width - 114px; y: 4px; width: 24px; height: 24px; border-radius: 12px; background: stream-minimize-touch.pressed ? #c0bfbc : stream-minimize-touch.has-hover ? #deddda : root.window-active ? #e6e6e6 : transparent; accessible-role: button; accessible-label: "Minimize"; accessible-action-default => { stream-minimize-touch.clicked(); } Rectangle { x: 8px; y: 13px; width: 8px; height: 0.75px; background: root.window-active || stream-minimize-touch.has-hover || stream-minimize-touch.pressed ? #454545 : #898989; } stream-minimize-touch := TouchArea { clicked => { root.minimize-stream-window(); } } } stream-maximize-button := Rectangle { x: parent.width - 74px; y: 4px; width: 24px; height: 24px; border-radius: 12px; background: stream-maximize-touch.pressed ? #c0bfbc : stream-maximize-touch.has-hover ? #deddda : root.window-active ? #e6e6e6 : transparent; accessible-role: button; accessible-label: root.window-maximized ? "Restore" : "Maximize"; accessible-action-default => { stream-maximize-touch.clicked(); } if !root.window-maximized: Rectangle { x: 8px; y: 8px; width: 8px; height: 8px; background: transparent; border-width: 1px; border-color: root.window-active || stream-maximize-touch.has-hover || stream-maximize-touch.pressed ? #454545 : #898989; } if root.window-maximized: Rectangle { x: 9px; y: 7px; width: 8px; height: 8px; background: transparent; border-width: 1px; border-color: root.window-active || stream-maximize-touch.has-hover || stream-maximize-touch.pressed ? #454545 : #898989; } if root.window-maximized: Rectangle { x: 7px; y: 9px; width: 8px; height: 8px; background: stream-maximize-button.background; border-width: 1px; border-color: root.window-active || stream-maximize-touch.has-hover || stream-maximize-touch.pressed ? #454545 : #898989; } stream-maximize-touch := TouchArea { clicked => { root.toggle-maximize-stream-window(); } } } stream-close-button := Rectangle { x: parent.width - 34px; y: 4px; width: 24px; height: 24px; border-radius: 12px; background: stream-close-touch.pressed ? #b2161d : stream-close-touch.has-hover ? #e01b24 : root.window-active ? #e6e6e6 : transparent; accessible-role: button; accessible-label: "Close"; accessible-action-default => { stream-close-touch.clicked(); } Path { width: parent.width; height: parent.height; viewbox-width: 24; viewbox-height: 24; commands: "M 14.75 14.75 L 8.25 8.25 M 14.75 8.25 L 8.25 14.75"; stroke: stream-close-touch.has-hover || stream-close-touch.pressed ? white : root.window-active ? #454545 : #898989; stroke-width: 1px; } stream-close-touch := TouchArea { clicked => { root.close-stream-window(); } } } Rectangle { y: parent.height - 1px; height: 1px; background: #d5d3d0; } } content-layer := Rectangle { y: root.titlebar-height; width: parent.width; height: parent.height - self.y; background: black; clip: true; // Keep the ImGui tab strip behavior, including pointer-drag reordering. Rectangle { y: 0px; height: root.tabs.length > 1 ? 30px : 0px; visible: !root.fullscreen-enabled && root.tabs.length > 1; background: #f1f2f4; z: 10; HorizontalLayout { spacing: 1px; for tab[index] in root.tabs: tab-item := Rectangle { width: min(190px, max(110px, (parent.width - 12px) / root.tabs.length)); background: index == root.selected-tab ? white : tab-touch.has-hover || root.dragging-tab == index ? #e5e7eb : #d8dbe0; border-width: root.dragging-tab == index ? 1px : 0px; border-color: #2463c7; Rectangle { width: parent.width - 27px; height: parent.height; background: transparent; if root.srtp-enabled: Text { x: 0px; width: 12px; height: parent.height; text: FontAwesomeIcons.shield-halved; color: #30343b; font-family: "Font Awesome 6 Free"; font-weight: 900; font-size: ImGuiFontStyle.base; horizontal-alignment: center; vertical-alignment: center; } Text { x: root.srtp-enabled ? 16px : 0px; width: parent.width - self.x; height: parent.height; text: tab.title; color: #30343b; font-size: ImGuiFontStyle.base; overflow: elide; vertical-alignment: center; } } Rectangle { y: parent.height - 2px; height: 2px; background: index == root.selected-tab ? #3b82f6 : transparent; } tab-touch := TouchArea { width: parent.width - 27px; changed pressed => { if (self.pressed) { root.dragging-tab = index; } else if (root.dragging-tab == index) { root.reorder-tab(index, tab-item.x + self.mouse-x, tab-item.width); root.dragging-tab = -1; } } clicked => { root.selected-tab = index; root.select-tab(index); } } IconButton { x: parent.width - 27px; y: 1px; width: 27px; height: 27px; z: 2; icon: FontAwesomeIcons.xmark; icon-size: 11px; icon-color: #555c66; danger: true; clicked => { root.close-tab(tab.remote-id); } } } } } video := Rectangle { y: root.fullscreen-enabled ? 0px : (root.tabs.length > 1 ? 30px : 0px); height: parent.height - self.y; background: black; clip: true; frame-image := Image { width: parent.width; height: parent.height; source: root.frame; image-fit: contain; visible: root.has-frame; } Text { // A connection state and the frame-waiting state may change in // the same UI tick. Render them through one text item so two // independent labels can never occupy the center together. visible: !root.has-frame && (root.receiving-text != "" || root.status-text != ""); text: root.receiving-text != "" ? root.receiving-text : root.status-text; color: root.receiving-text != "" ? #ffffffea : white; font-size: root.receiving-text != "" ? 14px : ImGuiFontStyle.prominent; horizontal-alignment: center; vertical-alignment: center; } drop-zone := DropArea { can-drop(event) => { return root.can-drop-file(event.data) ? DragAction.copy : DragAction.none; } dropped(event) => { root.file-dropped(event.data); return DragAction.copy; } } input-focus := FocusScope { focus-on-click: true; key-pressed(event) => { root.key-input(event.text, true, event.modifiers.control, event.modifiers.alt, event.modifiers.shift, event.modifiers.meta); accept } key-released(event) => { root.key-input(event.text, false, event.modifiers.control, event.modifiers.alt, event.modifiers.shift, event.modifiers.meta); accept } pointer := TouchArea { pointer-event(event) => { let over-control = self.mouse-x >= control.x && self.mouse-x <= control.x + control.width && self.mouse-y >= control.y && self.mouse-y <= control.y + control.height; if event.kind == PointerEventKind.down && event.button == PointerEventButton.left && over-control { root.begin-control-drag(self.mouse-x, self.mouse-y); } else if root.control-dragging && (event.kind == PointerEventKind.up || event.kind == PointerEventKind.cancel) { root.end-control-drag(); } else if !root.control-dragging { root.pointer-input(event.button, event.kind, self.mouse-x, self.mouse-y); } } moved => { if root.control-dragging { root.move-control-drag(self.mouse-x, self.mouse-y); } } scroll-event(event) => { if self.mouse-x < control.x || self.mouse-x > control.x + control.width || self.mouse-y < control.y || self.mouse-y > control.y + control.height { root.scroll-input(event.delta-x, event.delta-y, self.mouse-x, self.mouse-y); } accept } } } // Floating control bar, matching the original top-left overlay. control := Rectangle { x: root.control-dragging ? root.control-drag-x : root.control-docked-left ? 0px : parent.width - self.width; y: min(max(0px, root.control-pos-y), parent.height - self.height); width: root.control-expanded ? min(300px, parent.width) : 20px; height: root.stats-visible && root.control-expanded ? min(180px, parent.height) : 38px; background: white; border-width: 1px; border-color: ImGuiLineStyle.border; border-radius: 6px; z: 8; clip: true; // Keep width changes atomic. When docked right, animating both // x and the clip width can leave newly revealed buttons outside // Slint's damage region until they receive a hover repaint. animate height { duration: 60ms; easing: ease-out; } if root.control-expanded && !root.control-docked-left: Rectangle { x: 31px; y: 12px; width: 2px; height: 15px; background: ImGuiLineStyle.control-separator; } if root.control-expanded: display-button := ControlBarButton { x: root.control-docked-left ? 9px : 42px; y: 7px; icon: FontAwesomeIcons.display; badge: root.selected-display + 1; tooltip: StreamStrings.select-display; clicked => { root.display-menu-open = !root.display-menu-open; root.shortcut-menu-open = false; } } if root.control-expanded: shortcut-button := ControlBarButton { x: root.control-docked-left ? 41px : 74px; y: 7px; icon: FontAwesomeIcons.keyboard; tooltip: StreamStrings.send-shortcut; clicked => { root.shortcut-menu-open = !root.shortcut-menu-open; root.display-menu-open = false; } } if root.control-expanded: mouse-button := ControlBarButton { x: root.control-docked-left ? 73px : 106px; y: 7px; icon: FontAwesomeIcons.computer-mouse; slashed: !root.mouse-control-enabled; tooltip: root.mouse-control-enabled ? StreamStrings.release-mouse : StreamStrings.control-mouse; clicked => { root.toggle-mouse-control(); } } if root.control-expanded: audio-button := ControlBarButton { x: root.control-docked-left ? 105px : 138px; y: 7px; icon: FontAwesomeIcons.volume-high; slashed: !root.audio-enabled; tooltip: root.audio-enabled ? StreamStrings.mute : StreamStrings.audio; clicked => { root.toggle-audio(); } } if root.control-expanded: file-button := ControlBarButton { x: root.control-docked-left ? 137px : 170px; y: 7px; icon: FontAwesomeIcons.folder-open; tooltip: StreamStrings.select-file; clicked => { root.select-file(); } } if root.control-expanded: stats-button := ControlBarButton { x: root.control-docked-left ? 169px : 202px; y: 7px; icon: FontAwesomeIcons.signal; selected: root.stats-visible; tooltip: root.stats-visible ? StreamStrings.hide-stats : StreamStrings.show-stats; clicked => { root.toggle-stats(); } } if root.control-expanded: fullscreen-button := ControlBarButton { x: root.control-docked-left ? 201px : 234px; y: 7px; icon: root.fullscreen-enabled ? FontAwesomeIcons.compress : FontAwesomeIcons.expand; tooltip: root.fullscreen-enabled ? StreamStrings.exit-fullscreen : StreamStrings.fullscreen; clicked => { root.toggle-fullscreen(); } } if root.control-expanded: close-button := ControlBarButton { x: root.control-docked-left ? 233px : 266px; y: 7px; icon: FontAwesomeIcons.xmark; tooltip: StreamStrings.disconnect; clicked => { root.disconnect(); } } if root.control-expanded && root.control-docked-left: Rectangle { x: 267px; y: 12px; width: 2px; height: 15px; background: ImGuiLineStyle.control-separator; } collapse-button := ControlBarButton { x: root.control-expanded ? (root.control-docked-left ? 275px : 10px) : 2px; y: 7px; width: 15px; icon: root.control-expanded ? (root.control-docked-left ? FontAwesomeIcons.angle-left : FontAwesomeIcons.angle-right) : (root.control-docked-left ? FontAwesomeIcons.angle-right : FontAwesomeIcons.angle-left); tooltip: root.control-expanded ? StreamStrings.collapse-control : StreamStrings.expand-control; clicked => { root.control-expanded = !root.control-expanded; } } if root.stats-visible && root.control-expanded: stats-table := Rectangle { x: 14px; y: 38px; width: parent.width - 28px; height: 128px; background: transparent; private property row-height: 16px; private property label-column-width: 60px; private property loss-column-width: 66px; private property value-column-width: (self.width - self.label-column-width - self.loss-column-width) / 2; Rectangle { y: 0px; height: 1px; background: ImGuiLineStyle.border; } Rectangle { y: 0px; height: stats-table.row-height; Text { x: stats-table.label-column-width + 4px; width: stats-table.value-column-width - 8px; text: StreamStrings.stats-in; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; } Text { x: stats-table.label-column-width + stats-table.value-column-width + 4px; width: stats-table.value-column-width - 8px; text: StreamStrings.stats-out; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; } Text { x: stats-table.label-column-width + stats-table.value-column-width * 2 + 4px; width: stats-table.loss-column-width - 8px; text: StreamStrings.stats-loss-rate; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; overflow: elide; } Rectangle { y: parent.height - 1px; height: 1px; background: ImGuiLineStyle.border; } } for row[index] in root.stats-rows: Rectangle { y: (index + 1) * stats-table.row-height; height: stats-table.row-height; Text { x: 4px; width: stats-table.label-column-width - 8px; text: row.label; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; } Text { x: stats-table.label-column-width + 4px; width: stats-table.value-column-width - 8px; text: row.inbound; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; overflow: elide; } Text { x: stats-table.label-column-width + stats-table.value-column-width + 4px; width: stats-table.value-column-width - 8px; text: row.outbound; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; overflow: elide; } Text { x: stats-table.label-column-width + stats-table.value-column-width * 2 + 4px; width: stats-table.loss-column-width - 8px; text: row.loss-rate; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; overflow: elide; } Rectangle { y: parent.height - 1px; height: 1px; background: ImGuiLineStyle.border; } } for metric[index] in [ { label: "FPS:", value: root.stats-fps }, { label: StreamStrings.stats-resolution + ":", value: root.stats-resolution }, { label: StreamStrings.stats-connection-mode + ":", value: root.stats-connection-mode }, ]: Rectangle { y: (index + 5) * stats-table.row-height; height: stats-table.row-height; Text { x: 4px; width: stats-table.label-column-width - 8px; text: metric.label; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; } Text { x: stats-table.label-column-width + 4px; width: stats-table.value-column-width - 8px; text: metric.value; color: #30343b; font-size: ImGuiFontStyle.small; vertical-alignment: center; overflow: elide; } Rectangle { y: parent.height - 1px; height: 1px; background: ImGuiLineStyle.border; } } } } if root.display-menu-open: Rectangle { x: control.x + (root.control-docked-left ? 9px : 42px); y: control.y + 40px; width: 180px; height: min(180px, root.displays.length * 30px + 8px); background: white; border-width: 1px; border-color: ImGuiLineStyle.border; border-radius: 5px; z: 11; VerticalLayout { padding: 4px; spacing: 1px; for display[index] in root.displays: Rectangle { height: 29px; background: display-touch.has-hover || index == root.selected-display ? #e8eef9 : transparent; Text { x: 8px; text: display; color: #30343b; font-size: ImGuiFontStyle.body; vertical-alignment: center; } display-touch := TouchArea { clicked => { root.selected-display = index; root.switch-display(index); root.display-menu-open = false; } } } } } if root.shortcut-menu-open: Rectangle { x: control.x + (root.control-docked-left ? 41px : 74px); y: control.y + 40px; width: 150px; height: 68px; background: white; border-width: 1px; border-color: ImGuiLineStyle.border; border-radius: 5px; z: 11; VerticalLayout { padding: 4px; spacing: 1px; for shortcut in ["Ctrl+Alt+Del", "Win+L"]: Rectangle { height: 29px; background: shortcut-touch.has-hover ? #e8eef9 : transparent; Text { x: 8px; text: shortcut; color: #30343b; font-size: ImGuiFontStyle.body; vertical-alignment: center; } shortcut-touch := TouchArea { clicked => { root.send-shortcut(shortcut); root.shortcut-menu-open = false; } } } } } // Transfer progress overlay at bottom-left. if root.file-transfer-visible: Rectangle { x: 18px; y: parent.height - min(210px, parent.height * 0.35); width: min(430px, parent.width * 0.6); height: min(190px, parent.height * 0.32); background: #fffffff0; border-width: 1px; border-color: ImGuiLineStyle.border; border-radius: 6px; z: 7; Text { x: 12px; y: 8px; text: StreamStrings.file-transfer; color: #2d3138; font-weight: 600; } IconButton { x: parent.width - 32px; y: 1px; icon: FontAwesomeIcons.xmark; icon-size: 13px; clicked => { root.close-file-transfer(); } } ScrollView { x: 10px; y: 32px; width: parent.width - 20px; height: parent.height - 42px; VerticalLayout { // Slint's ScrollView draws its vertical scrollbar over // the viewport. Reserve a gutter so transfer content // never extends underneath it. padding-right: 16px; spacing: 8px; for entry in root.file-transfers: VerticalLayout { spacing: 3px; HorizontalLayout { height: 18px; Text { text: entry.name; color: #30343b; font-size: ImGuiFontStyle.body; overflow: elide; } Text { width: 80px; text: entry.status; color: #5c6470; font-size: ImGuiFontStyle.body; horizontal-alignment: right; } } Rectangle { height: 7px; background: #dfe3e8; border-radius: 3px; Rectangle { x: 0px; y: 0px; width: parent.width * max(0, min(1, entry.progress)); height: parent.height; background: #2463c7; border-radius: 3px; } } HorizontalLayout { height: 14px; Text { text: round(entry.progress * 100) + "% " + entry.speed; color: #6a717c; font-size: ImGuiFontStyle.small; } Text { text: entry.size; color: #6a717c; font-size: ImGuiFontStyle.small; horizontal-alignment: right; } } } } } } } } if root.custom-titlebar && !root.fullscreen-enabled: Rectangle { width: parent.width; height: parent.height; background: transparent; border-width: 1px; border-color: #aaa8a6; border-radius: root.window-maximized ? 0px : root.window-corner-radius; z: 200; } } }