GeezerVison is showing github.com — feat: Linux platform (GTK 4) by triniwiz · Pull Request #11620 · NativeScript/NativeScript
Conversation
triniwiz
commented
Nov 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Adds support for the new Linux runtime (GTK 4).
Part of #27
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Adds a linux platform to @nativescript/core and @nativescript/webpack,
running on the NativeScript Linux runtime (C APIs from metadata).
- webpack: linux platform, __LINUX__ / global.isLinux, CommonJS output
- core: isLinux, LinuxApplication, LinuxNativeWindow (GtkWindow)
- views: core's own measure/layout pass (as on iOS); containers are
GtkFixed with a JS custom layout manager placing children at the
computed frames, leaf widgets measured with gtk_widget_measure
- styling through per-widget GTK CSS; Pango markup for formatted text
- Label, Button, Page, Frame, ActionBar, layouts, file system (GIO),
http (runtime fetch), image source (GdkTexture), settings, device,
screen, connectivity; remaining widgets are placeholders for now
- types-minimal: generated GTK / GLib / Pango / Cairo typings
The program name is the app id from nativescript.config, so desktops match
windows to <app-id>.desktop; the window icon comes from the staged icon
theme. linux.window sets the initial size, minimum size, resizability and
title. res:// images resolve from App_Resources/Linux/images.
…s, ActivityIndicator, SearchBar, HtmlView
- containers inside GTK scrolling viewports report their NativeScript frame
as their size; only views NativeScript never laid out run a layout pass
- widget CSS changes re-measure the owning view; sub-part styling (switch
thumb, scale highlight, progress fill, links) via scoped display CSS
Image is a GtkPicture over the source's GdkTexture (measured like iOS),
pickers use GtkCalendar, spin buttons and GtkDropDown, SegmentedBar is a
linked toggle button group. Also fixes TextView sizing (GTK validates text
lines lazily) and drops the platformCheck import that webpack 5.112 leaves
unresolved.
tap / doubleTap (GtkGestureClick), longPress, pan and touch (GtkGestureDrag),
swipe, pinch (GtkGestureZoom) and rotation, with iOS semantics: taps don't
fire for drags or long presses, pans start after movement, still releases
aren't swipes. Signal trampolines now take typed (double / int) arguments.
Modal windows over the app window built from GTK widgets (GTK 4.6 has no
GtkAlertDialog): primary button is the default, Return in an entry submits,
closing the window resolves as cancel unless cancelable is false.
Tweens opacity, backgroundColor, translate, scale, rotate, width and height
with CSS / Core Animation cubic-bezier curves, delays, iterations (including
infinite), sequential playback and cancel. GTK 4.6's GL renderer shears
views that are both rotated and translucent (fine with GSK_RENDERER=cairo
and newer GTK).
Virtualized rows: a GtkStringList of placeholders backs a GtkListView, and
each bound row hosts a NativeScript view from the item template (itemLoading,
template selector, rowHeight, itemTap, loadMoreItems, scrollToIndex).
Views a parent hosts in a GTK widget (list rows, ActionBar.titleView) now
answer GTK's measure with a NativeScript measure and lay themselves out.
Each item's view is a hosted page laid out by NativeScript; items load once
the TabView loads (as on iOS); tab switches feed selectedIndex; tab text,
selected text, background and font size through scoped CSS.
SplitView lays out primary | supplementary | secondary | inspector columns
from the preferred width fractions, with show/hide per role. WebView opens
pages in the desktop browser until WebKitGTK 6.0 is in the metadata.
As on iOS, livesync goes to the root view, which replaces the page whose
module changed and resets the root content when nothing handled it
(Frame.reloadPage is Android only).
…ings with macro constants
nx-cloud
Bot
commented
Nov 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
View your CI Pipeline Execution ↗ for commit 6122649
| Command |
Status |
Duration |
Result |
nx run-many -t build -p core,webpack5,vite |
✅ Succeeded |
25s |
View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-11-12 00:55:57 UTC
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
pkg-pr-new
Bot
commented
Nov 7, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
Open in StackBlitz
npm i https://pkg.pr.new/@nativescript/core@11620
npm i https://pkg.pr.new/@nativescript/vite@11620
npm i https://pkg.pr.new/@nativescript/webpack@11620
commit: 6122649
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
'system' (the default) follows the desktop. 'light' or 'dark' set GtkSettings for the app, so a light app theme stays readable on a dark desktop, like a fixed Android app theme.
Frames come from the window's GDK frame clock (as CADisplayLink / Choreographer on iOS / Android), in g_get_monotonic_time() milliseconds; a ~60 Hz timer only until the first window exists.
This was referenced Nov 7, 2026
GTK gave the returning page's first focusable widget focus, and a ScrollView holding it scrolled
back to it. The page's focused view is now restored instead.
File, Folder and ImageSource read the app folder through the runtime's
app.nsbundle when one is mounted (zero-copy for unencrypted bundles);
writes inside it fail with EROFS.
Unclosed or stray tags and raw & / < in hrefs made GTK reject the whole
markup (the label kept its old text). Open tags are now tracked and closed,
and href values escaped.
Encodes the PNG in memory instead of leaving ns-image-<ms>.png files (which
collided within the same millisecond) in the cache folder.
HTML content may be untrusted: file://, custom schemes and desktop
launchers no longer open.
…ityIndicator spin (#11623)
* fix(linux): CSS keyframe animations write keyframe values
KeyframeAnimation sets the style's keyframe values when it starts, and they win
over local values, so the Linux Animation's local writes didn't show until the
animation ended (animate-pulse never pulsed). Like iOS and Android, an animation
with valueSource 'keyframe' now writes the keyframe values.
* feat(linux): mouseEnter, mouseLeave and mouseMove events
A GtkEventControllerMotion, attached while any of them has a listener, raises
the events (mouseMove with getX/getY) and keeps the hover visual state, as
Windows does. MasonKit's :hover and onMouseLeave relied on them.
* fix(linux): ActivityIndicator spins when busy is set before it's shown
GTK left the spinner's CSS animation still when gtk_spinner_start ran before
the widget was on screen (or inside its map signal), until a theme change
restyled it. It now starts on the turn after the spinner is mapped.
…er the placeholder
On Linux, Application.run() fires the one-shot launch event while the HMR
placeholder boots, before the app entry loads. Angular registers its launch
listener later and calls run() without an entry, which the patched run()
ignored, so the app never bootstrapped. Replay the launch event once and
install the root a listener supplies.
Core reads the app config with require('~/package.json'), but the core
bundle served it as an ESM default export, so require() returned
{ default } and Linux never set the program name, app name or window
title. Serve it as CommonJS that loads the CLI-written package.json on
device, with nativescript.config as the fallback.
FPSCallback started and stopped continuous updating on the window's frame
clock (through a tick callback) for every animation. GTK 4.6 resets its
frame-time smoothing each time updating starts, and doing that repeatedly
stalls GTK's own CSS animations: a GtkSpinner stops turning while short
view animations run. Request the next UPDATE phase from the clock on each
frame instead, as requestAnimationFrame does.
Forward navigation unloads the outgoing page but leaves it in the frame,
so going back showed it without raising loaded and its views stayed
unloaded.
This branch has not been deployed
No deployments
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|