Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d5c257c
feat(linux): GTK 4 platform
triniwiz Nov 6, 2026
0600d56
feat(linux): app id, window icon and window options
triniwiz Nov 7, 2026
3128569
feat(linux): ScrollView, TextField, TextView, Switch, Slider, Progres…
triniwiz Nov 7, 2026
0206d7e
feat(linux): Image, DatePicker, TimePicker, ListPicker, SegmentedBar
triniwiz Nov 7, 2026
13950b4
feat(linux): gestures on GTK 4 controllers
triniwiz Nov 7, 2026
7b3e9f1
feat(linux): alert, confirm, prompt, login and action dialogs
triniwiz Nov 7, 2026
8a88bbd
feat(linux): frame-driven animations
triniwiz Nov 7, 2026
bc97fad
feat(linux): ListView on GtkListView
triniwiz Nov 7, 2026
51d8cb0
feat(linux): TabView on GtkNotebook
triniwiz Nov 7, 2026
40abd00
feat(linux): SplitView layout, WebView fallback
triniwiz Nov 7, 2026
396195c
fix(linux): hot module replacement reloads the edited page
triniwiz Nov 7, 2026
c293fd2
feat(core): linux native-api-usage.json for metadata filtering, C typ…
triniwiz Nov 7, 2026
53f6ad1
feat(vite): linux platform (build, HMR via the runtime's ns:module)
triniwiz Nov 7, 2026
acd2924
fix(vite): purge transform caches on TypeScript flavor hot updates
triniwiz Nov 7, 2026
59ce879
fix(linux): AppStream-valid default metainfo (description, release)
triniwiz Nov 7, 2026
d9beac2
chore(linux): default icon from the app templates' NativeScript artwork
triniwiz Nov 7, 2026
deee1d6
feat(linux): linux.appearance pins a light or dark GTK theme
triniwiz Nov 7, 2026
add6df5
feat(linux): requestAnimationFrame at the display refresh rate
triniwiz Nov 7, 2026
bb2d0c4
fix(linux): keep a page's focus across navigation
triniwiz Nov 7, 2026
9b2e9f3
docs(linux): appearance and config docs without toolkit details
triniwiz Nov 7, 2026
71e9fe8
feat(linux): read app files from the app bundle
triniwiz Nov 7, 2026
e5ac69a
feat(linux): bundle, bundleUnpack, sourceProtect and fuses config
triniwiz Nov 7, 2026
7906dfb
fix(linux): balanced, escaped markup from HtmlView html
triniwiz Nov 7, 2026
b612c2c
fix(linux): ImageSource.toBase64String without a temp file
triniwiz Nov 7, 2026
447f6ed
fix(linux): HtmlView only opens http, https and mailto links
triniwiz Nov 7, 2026
697a377
feat(linux): linux.v8Flags config
triniwiz Nov 7, 2026
9f94e72
fix(linux): CSS keyframe animations, mouse enter/leave/move and Activ…
triniwiz Nov 8, 2026
67f1c96
fix(linux): restore a page's focus without scrolling to it (#11625)
triniwiz Nov 8, 2026
ecff5a5
fix(vite): replay the launch event for frameworks that call run() aft…
triniwiz Nov 8, 2026
77867dd
fix(vite): read the CLI-written package.json in the HMR core bundle
triniwiz Nov 8, 2026
3456c82
fix(linux): request animation frames one at a time
triniwiz Nov 8, 2026
6122649
fix(linux): load a page again when navigating back to it
triniwiz Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/core/animation-frame/animation-native.linux.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// GDK frame times are g_get_monotonic_time() microseconds
export function getTimeInFrameBase(): number {
return Number(g_get_monotonic_time()) / 1000;
}
124 changes: 124 additions & 0 deletions packages/core/application-settings/index.linux.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { outPointer } from '../utils/gtk.linux';
import * as Common from './application-settings-common';

// JSON file in $XDG_CONFIG_HOME/<application name>/settings.json
let cache: Record<string, any> | null = null;

function path(): string {
const app = g_get_prgname() || 'nativescript-app';
return `${g_get_user_config_dir()}/${app}/settings.json`;
}

function load(): Record<string, any> {
if (cache) {
return cache;
}
const contents = outPointer();
cache = {};
if (g_file_get_contents(path(), contents, null, null)) {
try {
cache = JSON.parse(interop.stringFromCString(contents.value)) ?? {};
} catch {}
g_free(contents.value);
}
return cache;
}

function save(): boolean {
const file = path();
g_mkdir_with_parents(file.substring(0, file.lastIndexOf('/')), 0o700);
return !!g_file_set_contents(file, JSON.stringify(load()), -1, null);
}

function values() {
const data = load();
return {
HasKey: (key: string) => Object.prototype.hasOwnProperty.call(data, key),
Lookup: (key: string) => data[key],
Insert: (key: string, value: any) => {
data[key] = value;
save();
},
Remove: (key: string) => {
delete data[key];
save();
},
Clear: () => {
for (const key of Object.keys(data)) delete data[key];
save();
},
Keys: () => Object.keys(data),
};
}

export function hasKey(key: string): boolean | undefined {
if (!Common.checkKey(key)) {
return;
}

return values().HasKey(key);
}

function getValue(key: string, defaultValue: any): any {
if (!Common.checkKey(key)) {
return undefined;
}
const settings = values();
return settings.HasKey(key) ? settings.Lookup(key) : defaultValue;
}

export function getBoolean(key: string, defaultValue?: boolean): boolean | undefined {
return getValue(key, defaultValue);
}

export function getString(key: string, defaultValue?: string): string | undefined {
return getValue(key, defaultValue);
}

export function getNumber(key: string, defaultValue?: number): number | undefined {
return getValue(key, defaultValue);
}

function setValue(key: string, value: any, valueType: string): void {
if (!Common.checkKey(key)) {
return;
}
if (!Common.ensureValidValue(value, valueType)) {
return;
}
values().Insert(key, value);
}

export function setBoolean(key: string, value: boolean): void {
setValue(key, value, 'boolean');
}

export function setString(key: string, value: string): void {
setValue(key, value, 'string');
}

export function setNumber(key: string, value: number): void {
setValue(key, value, 'number');
}

export function remove(key: string): void {
if (!Common.checkKey(key)) {
return;
}
const settings = values();
if (settings.HasKey(key)) {
settings.Remove(key);
}
}

export function clear(): void {
values().Clear();
}

export function flush(): boolean {
return save();
}

export function getAllKeys(): Array<string> {
return values().Keys();
}
7 changes: 6 additions & 1 deletion packages/core/application/application-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { View } from '../ui/core/view';
import type { Frame } from '../ui/frame';
import type { NavigationEntry } from '../ui/frame/frame-interfaces';
import type { StyleScope } from '../ui/styling/style-scope';
import type { AndroidApplication as AndroidApplicationType, iOSApplication as iOSApplicationType, WindowsApplication as WindowsApplicationType } from '.';
import type { AndroidApplication as AndroidApplicationType, iOSApplication as iOSApplicationType, WindowsApplication as WindowsApplicationType, LinuxApplication as LinuxApplicationType } from '.';
import type { ApplicationEventData, CssChangedEventData, DiscardedErrorEventData, FontScaleChangedEventData, InitRootViewEventData, LaunchEventData, LoadAppCSSEventData, NativeScriptError, OrientationChangedEventData, SystemAppearanceChangedEventData, LayoutDirectionChangedEventData, UnhandledErrorEventData, SceneOpenURLContextsEventData, SceneContinueUserActivityEventData, ScenePerformActionForShortcutItemEventData } from './application-interfaces';
import { applyAccessibilityCssToRoot, readyInitAccessibilityCssHelper, readyInitFontScale } from '../accessibility/accessibility-common';
import { getActiveWindow, getAppMainEntry, getAutoSystemAppearanceChanged, isAppInBackground, setActiveWindow, setAppInBackground, setAppMainEntry, setAutoSystemAppearanceChanged } from './helpers-common';
Expand Down Expand Up @@ -831,6 +831,7 @@ export class ApplicationCommon {
ios: this.ios,
android: this.android,
windows: this.windows,
linux: this.linux,
...additionalLanchEventData,
};
this.notify(launchArgs);
Expand Down Expand Up @@ -1177,6 +1178,10 @@ export class ApplicationCommon {
return undefined;
}

get linux(): LinuxApplicationType {
return undefined;
}

get AndroidApplication() {
return this.android;
}
Expand Down
14 changes: 13 additions & 1 deletion packages/core/application/application.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,13 +376,25 @@ export class iOSApplication extends ApplicationCommon {
shouldDelayLaunchEvent: boolean;
}
export class WindowsApplication extends ApplicationCommon {

getRootView(): View;

run(entry?: string | NavigationEntry): void;

getNativeApplication(): Microsoft.UI.Xaml.Application;
}

/**
* The Linux (GTK 4) application.
*/
export class LinuxApplication extends ApplicationCommon {
getRootView(): View;

run(entry?: string | NavigationEntry): void;

/**
* The `GtkApplication*`.
*/
getNativeApplication(): interop.Pointer;
}

export const VALID_FONT_SCALES: number[];
Expand Down
Loading
Loading