mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
refactor: rework extension API for iron-remote-desktop (#762)
This commit is contained in:
Generated
-13
@@ -2827,8 +2827,6 @@ dependencies = [
|
||||
"resize",
|
||||
"rgb",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"smallvec",
|
||||
"softbuffer",
|
||||
"tap",
|
||||
@@ -4716,17 +4714,6 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-wasm-bindgen"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_bytes"
|
||||
version = "0.11.17"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct DesktopSize {
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl DesktopSize {
|
||||
pub fn init(width: u16, height: u16) -> Self {
|
||||
DesktopSize { width, height }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! extension_match {
|
||||
( @ $jsval:expr, $value:ident, String, $operation:block ) => {{
|
||||
if let Some($value) = $jsval.as_string() {
|
||||
$operation
|
||||
} else {
|
||||
warn!("Unexpected value for extension {}", stringify!($ident));
|
||||
}
|
||||
}};
|
||||
( @ $jsval:expr, $value:ident, f64, $operation:block ) => {{
|
||||
if let Some($value) = $jsval.as_f64() {
|
||||
$operation
|
||||
} else {
|
||||
warn!("Unexpected value for extension {}", stringify!($ident));
|
||||
}
|
||||
}};
|
||||
( @ $jsval:expr, $value:ident, bool, $operation:block ) => {{
|
||||
if let Some($value) = $jsval.as_bool() {
|
||||
$operation
|
||||
} else {
|
||||
warn!("Unexpected value for extension {}", stringify!($ident));
|
||||
}
|
||||
}};
|
||||
( @ $jsval:expr, $value:ident, JsValue, $operation:block ) => {{
|
||||
let $value = $jsval;
|
||||
$operation
|
||||
}};
|
||||
|
||||
( match $ext:ident ; $( | $value:ident : $ty:ident | $operation:block ; )* ) => {
|
||||
let ident = $ext.ident();
|
||||
|
||||
match ident {
|
||||
$( stringify!($value) => $crate::extension_match!( @ $ext.into_value(), $value, $ty, $operation ), )*
|
||||
unknown_extension => ::tracing::warn!("Unknown extension: {unknown_extension}"),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Extension {
|
||||
ident: String,
|
||||
value: JsValue,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Extension {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(ident: String, value: JsValue) -> Self {
|
||||
Self { ident, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl Extension {
|
||||
pub fn ident(&self) -> &str {
|
||||
self.ident.as_str()
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &JsValue {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn into_value(self) -> JsValue {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,18 @@
|
||||
mod clipboard;
|
||||
mod cursor;
|
||||
mod desktop_size;
|
||||
mod error;
|
||||
mod extension;
|
||||
mod input;
|
||||
mod session;
|
||||
|
||||
pub use clipboard::{ClipboardContent, ClipboardTransaction};
|
||||
pub use cursor::CursorStyle;
|
||||
pub use desktop_size::DesktopSize;
|
||||
pub use error::{IronError, IronErrorKind};
|
||||
pub use extension::Extension;
|
||||
pub use input::{DeviceEvent, InputTransaction};
|
||||
pub use session::{Session, SessionBuilder, SessionTerminationInfo};
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct DesktopSize {
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl DesktopSize {
|
||||
pub fn init(width: u16, height: u16) -> Self {
|
||||
DesktopSize { width, height }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RemoteDesktopApi {
|
||||
type Session: Session;
|
||||
@@ -194,8 +183,8 @@ macro_rules! export {
|
||||
self.0.supports_unicode_keyboard_shortcuts()
|
||||
}
|
||||
|
||||
pub fn extension_call(value: JsValue) -> Result<JsValue, IronError> {
|
||||
<<$api as RemoteDesktopApi>::Session>::extension_call(value).map_err(IronError)
|
||||
pub fn extension_call(ext: $crate::Extension) -> Result<JsValue, IronError> {
|
||||
<<$api as RemoteDesktopApi>::Session>::extension_call(ext).map_err(IronError)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,8 +249,8 @@ macro_rules! export {
|
||||
Self(self.0.force_clipboard_update_callback(callback))
|
||||
}
|
||||
|
||||
pub fn extension(&self, value: JsValue) -> Self {
|
||||
Self(self.0.extension(value))
|
||||
pub fn extension(&self, ext: $crate::Extension) -> Self {
|
||||
Self(self.0.extension(ext))
|
||||
}
|
||||
|
||||
pub async fn connect(&self) -> Result<Session, IronError> {
|
||||
|
||||
@@ -4,7 +4,7 @@ use web_sys::{js_sys, HtmlCanvasElement};
|
||||
use crate::clipboard::ClipboardTransaction;
|
||||
use crate::error::IronError;
|
||||
use crate::input::InputTransaction;
|
||||
use crate::DesktopSize;
|
||||
use crate::{DesktopSize, Extension};
|
||||
|
||||
pub trait SessionBuilder {
|
||||
type Session: Session;
|
||||
@@ -38,7 +38,7 @@ pub trait SessionBuilder {
|
||||
#[must_use]
|
||||
fn force_clipboard_update_callback(&self, callback: js_sys::Function) -> Self;
|
||||
#[must_use]
|
||||
fn extension(&self, value: JsValue) -> Self;
|
||||
fn extension(&self, ext: Extension) -> Self;
|
||||
#[expect(async_fn_in_trait)]
|
||||
async fn connect(&self) -> Result<Self::Session, Self::Error>;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ pub trait Session {
|
||||
physical_height: Option<u32>,
|
||||
);
|
||||
fn supports_unicode_keyboard_shortcuts(&self) -> bool;
|
||||
fn extension_call(value: JsValue) -> Result<JsValue, Self::Error>;
|
||||
fn extension_call(ext: Extension) -> Result<JsValue, Self::Error>;
|
||||
}
|
||||
|
||||
pub trait SessionTerminationInfo {
|
||||
|
||||
@@ -46,8 +46,6 @@ web-sys = { version = "0.3", features = ["HtmlCanvasElement"] }
|
||||
js-sys = "0.3"
|
||||
gloo-net = { version = "0.6", default-features = false, features = ["websocket", "http", "io-util"] }
|
||||
gloo-timers = { version = "0.3", default-features = false, features = ["futures"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde-wasm-bindgen = "0.6"
|
||||
|
||||
# Rendering
|
||||
softbuffer = { version = "0.4", default-features = false }
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// https://github.com/rustwasm/wasm-bindgen/issues/4080
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use core::cell::RefCell;
|
||||
use core::num::NonZeroU32;
|
||||
use core::time::Duration;
|
||||
@@ -15,7 +12,7 @@ use futures_util::io::{ReadHalf, WriteHalf};
|
||||
use futures_util::{select, AsyncWriteExt as _, FutureExt as _, StreamExt as _};
|
||||
use gloo_net::websocket;
|
||||
use gloo_net::websocket::futures::WebSocket;
|
||||
use iron_remote_desktop::{CursorStyle, DesktopSize, IronErrorKind};
|
||||
use iron_remote_desktop::{CursorStyle, DesktopSize, Extension, IronErrorKind};
|
||||
use ironrdp::cliprdr::backend::ClipboardMessage;
|
||||
use ironrdp::cliprdr::CliprdrClient;
|
||||
use ironrdp::connector::connection_activation::ConnectionActivationState;
|
||||
@@ -31,7 +28,6 @@ use ironrdp::session::{fast_path, ActiveStage, ActiveStageOutput, GracefulDiscon
|
||||
use ironrdp_core::WriteBuf;
|
||||
use ironrdp_futures::{single_sequence_step_read, FramedWrite};
|
||||
use rgb::AsPixels as _;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tap::prelude::*;
|
||||
use wasm_bindgen::JsValue;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
@@ -208,16 +204,12 @@ impl iron_remote_desktop::SessionBuilder for SessionBuilder {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
fn extension(&self, value: JsValue) -> Self {
|
||||
match serde_wasm_bindgen::from_value::<Extension>(value) {
|
||||
Ok(value) => match value {
|
||||
Extension::KdcProxyUrl(kdc_proxy_url) => self.0.borrow_mut().kdc_proxy_url = Some(kdc_proxy_url),
|
||||
Extension::Pcb(pcb) => self.0.borrow_mut().pcb = Some(pcb),
|
||||
Extension::DisplayControl(use_display_control) => {
|
||||
self.0.borrow_mut().use_display_control = use_display_control
|
||||
}
|
||||
},
|
||||
Err(error) => error!(%error, "Unsupported extension value"),
|
||||
fn extension(&self, ext: Extension) -> Self {
|
||||
iron_remote_desktop::extension_match! {
|
||||
match ext;
|
||||
|pcb: String| { self.0.borrow_mut().pcb = Some(pcb) };
|
||||
|kdc_proxy_url: String| { self.0.borrow_mut().kdc_proxy_url = Some(kdc_proxy_url) };
|
||||
|display_control: bool| { self.0.borrow_mut().use_display_control = display_control };
|
||||
}
|
||||
|
||||
self.clone()
|
||||
@@ -355,13 +347,6 @@ impl iron_remote_desktop::SessionBuilder for SessionBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
enum Extension {
|
||||
KdcProxyUrl(String),
|
||||
Pcb(String),
|
||||
DisplayControl(bool),
|
||||
}
|
||||
|
||||
pub(crate) type FastPathInputEvents = smallvec::SmallVec<[FastPathInputEvent; 2]>;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -814,13 +799,16 @@ impl iron_remote_desktop::Session for Session {
|
||||
}
|
||||
|
||||
fn supports_unicode_keyboard_shortcuts(&self) -> bool {
|
||||
// RDP does not support Unicode keyboard shortcuts (When key combinations are executed, only
|
||||
// plain scancode events are allowed to function correctly).
|
||||
// RDP does not support Unicode keyboard shortcuts.
|
||||
// When key combinations are executed, only plain scancode events are allowed to function correctly.
|
||||
false
|
||||
}
|
||||
|
||||
fn extension_call(_value: JsValue) -> Result<JsValue, Self::Error> {
|
||||
Ok(JsValue::null())
|
||||
fn extension_call(ext: Extension) -> Result<JsValue, Self::Error> {
|
||||
Err(
|
||||
IronError::from(anyhow::Error::msg(format!("unknown extension: {}", ext.ident())))
|
||||
.with_kind(IronErrorKind::General),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
type ExtensionValue = { Pcb: string } | { KdcProxyUrl: string } | { DisplayControl: boolean };
|
||||
|
||||
export class Extension {
|
||||
static init(ident: string, value: unknown): ExtensionValue {
|
||||
switch (ident) {
|
||||
case 'Pcb':
|
||||
if (typeof value === 'string') {
|
||||
return { Pcb: value };
|
||||
} else {
|
||||
throw new Error('Pcb must be a string');
|
||||
}
|
||||
case 'KdcProxyUrl':
|
||||
if (typeof value === 'string') {
|
||||
return { KdcProxyUrl: value };
|
||||
} else {
|
||||
throw new Error('KdcProxyUrl must be a string');
|
||||
}
|
||||
case 'DisplayControl':
|
||||
if (typeof value === 'boolean') {
|
||||
return { DisplayControl: value };
|
||||
} else {
|
||||
throw new Error('DisplayControl must be a boolean');
|
||||
}
|
||||
default:
|
||||
throw new Error(`Invalid extension type: ${ident}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ import init, {
|
||||
SessionTerminationInfo,
|
||||
ClipboardTransaction,
|
||||
ClipboardContent,
|
||||
Extension,
|
||||
} from '../../../crates/ironrdp-web/pkg/ironrdp_web';
|
||||
import { Extension } from './interfaces/Extension';
|
||||
|
||||
export default {
|
||||
init,
|
||||
@@ -26,3 +26,15 @@ export default {
|
||||
SessionTerminationInfo,
|
||||
Extension,
|
||||
};
|
||||
|
||||
export function preConnectionBlob(pcb: string): Extension {
|
||||
return new Extension('pcb', pcb);
|
||||
}
|
||||
|
||||
export function displayControl(enable: boolean): Extension {
|
||||
return new Extension('display_control', enable);
|
||||
}
|
||||
|
||||
export function kdcProxyUrl(url: string): Extension {
|
||||
return new Extension('kdc_proxy_url', url);
|
||||
}
|
||||
|
||||
@@ -1,5 +1 @@
|
||||
import type { ExtensionValue } from './ExtensionValue';
|
||||
|
||||
export interface Extension {
|
||||
init(ident: string, value: unknown): ExtensionValue;
|
||||
}
|
||||
export type Extension = unknown;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export type ExtensionValue = unknown;
|
||||
@@ -7,7 +7,6 @@ import type { SessionBuilder } from './SessionBuilder';
|
||||
import type { SessionTerminationInfo } from './SessionTerminationInfo';
|
||||
import type { ClipboardTransaction } from './ClipboardTransaction';
|
||||
import type { ClipboardContent } from './ClipboardContent';
|
||||
import type { Extension } from './Extension';
|
||||
|
||||
export interface RemoteDesktopModule {
|
||||
init: () => Promise<unknown>;
|
||||
@@ -21,5 +20,4 @@ export interface RemoteDesktopModule {
|
||||
SessionTerminationInfo: SessionTerminationInfo;
|
||||
ClipboardTransaction: ClipboardTransaction;
|
||||
ClipboardContent: ClipboardContent;
|
||||
Extension: Extension;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DesktopSize } from '../interfaces/DesktopSize';
|
||||
import type { ExtensionValue } from '../interfaces/ExtensionValue';
|
||||
import type { Extension } from '../interfaces/Extension';
|
||||
|
||||
export class Config {
|
||||
readonly username: string;
|
||||
@@ -9,7 +9,7 @@ export class Config {
|
||||
readonly serverDomain: string;
|
||||
readonly authToken: string;
|
||||
readonly desktopSize?: DesktopSize;
|
||||
readonly extensions: ExtensionValue[];
|
||||
readonly extensions: Extension[];
|
||||
|
||||
constructor(
|
||||
userData: { username: string; password: string },
|
||||
@@ -17,7 +17,7 @@ export class Config {
|
||||
configOptions: {
|
||||
destination: string;
|
||||
serverDomain: string;
|
||||
extensions: ExtensionValue[];
|
||||
extensions: Extension[];
|
||||
desktopSize?: DesktopSize;
|
||||
},
|
||||
) {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import type { DesktopSize } from '../interfaces/DesktopSize';
|
||||
import { Config } from './Config';
|
||||
import type { ExtensionValue } from '../interfaces/ExtensionValue';
|
||||
|
||||
type ExtensionConstructor = (ident: string, value: unknown) => ExtensionValue;
|
||||
import type { Extension } from '../interfaces/Extension';
|
||||
|
||||
/**
|
||||
* Builder class for creating Config objects with a fluent interface.
|
||||
@@ -19,8 +17,6 @@ type ExtensionConstructor = (ident: string, value: unknown) => ExtensionValue;
|
||||
* ```
|
||||
*/
|
||||
export class ConfigBuilder {
|
||||
private extensionConstructor: ExtensionConstructor;
|
||||
|
||||
private username: string = '';
|
||||
private password: string = '';
|
||||
private destination: string = '';
|
||||
@@ -28,17 +24,12 @@ export class ConfigBuilder {
|
||||
private serverDomain: string = '';
|
||||
private authToken: string = '';
|
||||
private desktopSize?: DesktopSize;
|
||||
|
||||
private extensions: ExtensionValue[] = [];
|
||||
private extensions: Extension[] = [];
|
||||
|
||||
/**
|
||||
* Creates a new ConfigBuilder instance.
|
||||
*
|
||||
* @param extensionConstructor - Function that creates extension values from identifiers and values.
|
||||
*/
|
||||
constructor(extensionConstructor: ExtensionConstructor) {
|
||||
this.extensionConstructor = extensionConstructor;
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Optional parameter
|
||||
@@ -109,12 +100,11 @@ export class ConfigBuilder {
|
||||
/**
|
||||
* Optional parameter
|
||||
*
|
||||
* @param ident - The identifier for the extension
|
||||
* @param value - The value for the extension
|
||||
* @param ext - The extension
|
||||
* @returns The builder instance for method chaining
|
||||
*/
|
||||
withExtension(ident: string, value: unknown): ConfigBuilder {
|
||||
this.extensions.push(this.extensionConstructor(ident, value));
|
||||
withExtension(ext: Extension): ConfigBuilder {
|
||||
this.extensions.push(ext);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ export class RemoteDesktopService {
|
||||
}
|
||||
|
||||
configBuilder(): ConfigBuilder {
|
||||
return new ConfigBuilder(this.module.Extension.init);
|
||||
return new ConfigBuilder();
|
||||
}
|
||||
|
||||
connect(config: Config): Observable<NewSessionInfo> {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { currentSession, userInteractionService } from '../../services/session.service';
|
||||
import { catchError, filter } from 'rxjs/operators';
|
||||
import type { UserInteraction, NewSessionInfo } from '../../../static/iron-remote-desktop';
|
||||
import { preConnectionBlob, displayControl, kdcProxyUrl } from '../../../static/iron-remote-desktop-rdp';
|
||||
import { from, of } from 'rxjs';
|
||||
import { toast } from '$lib/messages/message-store';
|
||||
import { showLogin } from '$lib/login/login-store';
|
||||
@@ -125,15 +126,16 @@
|
||||
.withServerDomain(domain)
|
||||
.withAuthToken(authtoken)
|
||||
.withDesktopSize(desktopSize)
|
||||
.withExtension('DisplayControl', true);
|
||||
.withExtension(displayControl(true));
|
||||
|
||||
if (pcb !== '') {
|
||||
configBuilder.withExtension('Pcb', pcb);
|
||||
configBuilder.withExtension(preConnectionBlob(pcb));
|
||||
}
|
||||
|
||||
if (kdc_proxy_url !== '') {
|
||||
configBuilder.withExtension('KdcProxyUrl', kdc_proxy_url);
|
||||
configBuilder.withExtension(kdcProxyUrl(kdc_proxy_url));
|
||||
}
|
||||
|
||||
const config = configBuilder.build();
|
||||
|
||||
from(userInteraction.connect(config))
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
import { setCurrentSessionActive, userInteractionService } from '../../services/session.service';
|
||||
import type { UserInteraction } from '../../../static/iron-remote-desktop';
|
||||
import IronRdp from '../../../static/iron-remote-desktop-rdp';
|
||||
import { preConnectionBlob, displayControl, kdcProxyUrl } from '../../../static/iron-remote-desktop-rdp';
|
||||
|
||||
let uiService: UserInteraction;
|
||||
let userInteraction: UserInteraction;
|
||||
let cursorOverrideActive = false;
|
||||
let showUtilityBar = false;
|
||||
|
||||
userInteractionService.subscribe((uis) => {
|
||||
if (uis != null) {
|
||||
uiService = uis;
|
||||
uiService.onSessionEvent((event) => {
|
||||
userInteractionService.subscribe((val) => {
|
||||
if (val != null) {
|
||||
userInteraction = val;
|
||||
userInteraction.onSessionEvent((event) => {
|
||||
if (event.type === 0) {
|
||||
uiService.setVisibility(true);
|
||||
userInteraction.setVisibility(true);
|
||||
} else if (event.type === 1) {
|
||||
setCurrentSessionActive(false);
|
||||
}
|
||||
@@ -23,7 +24,7 @@
|
||||
|
||||
userInteractionService.subscribe((uis) => {
|
||||
if (uis != null) {
|
||||
uiService = uis;
|
||||
userInteraction = uis;
|
||||
//read query params named data
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const data = urlParams.get('data');
|
||||
@@ -36,7 +37,7 @@
|
||||
const { hostname, gatewayAddress, domain, username, password, authtoken, kdc_proxy_url, pcb, desktopSize } =
|
||||
parsedData;
|
||||
|
||||
const configBuilder = uiService
|
||||
const configBuilder = userInteraction
|
||||
.configBuilder()
|
||||
.withUsername(username)
|
||||
.withPassword(password)
|
||||
@@ -45,19 +46,20 @@
|
||||
.withServerDomain(domain)
|
||||
.withAuthToken(authtoken)
|
||||
.withDesktopSize(desktopSize)
|
||||
.withExtension('DisplayControl', true);
|
||||
.withExtension(displayControl(true));
|
||||
|
||||
if (pcb !== '') {
|
||||
configBuilder.withExtension('Pcb', pcb);
|
||||
configBuilder.withExtension(preConnectionBlob(pcb));
|
||||
}
|
||||
|
||||
if (kdc_proxy_url !== '') {
|
||||
configBuilder.withExtension('KdcProxyUrl', kdc_proxy_url);
|
||||
configBuilder.withExtension(kdcProxyUrl(kdc_proxy_url));
|
||||
}
|
||||
|
||||
const config = configBuilder.build();
|
||||
|
||||
uiService.connect(config).then(() => {
|
||||
uiService.setVisibility(true);
|
||||
userInteraction.connect(config).then(() => {
|
||||
userInteraction.setVisibility(true);
|
||||
window.onresize = onWindowResize;
|
||||
});
|
||||
}
|
||||
@@ -66,7 +68,7 @@
|
||||
function onWindowResize() {
|
||||
const innerWidth = window.innerWidth;
|
||||
const innerHeight = window.innerHeight;
|
||||
uiService.resize(innerWidth, innerHeight);
|
||||
userInteraction.resize(innerWidth, innerHeight);
|
||||
}
|
||||
|
||||
function onUnicodeModeChange(e: MouseEvent) {
|
||||
@@ -80,14 +82,14 @@
|
||||
return;
|
||||
}
|
||||
|
||||
uiService.setKeyboardUnicodeMode(element.checked);
|
||||
userInteraction.setKeyboardUnicodeMode(element.checked);
|
||||
}
|
||||
|
||||
function toggleCursorKind() {
|
||||
if (cursorOverrideActive) {
|
||||
uiService.setCursorStyleOverride(null);
|
||||
userInteraction.setCursorStyleOverride(null);
|
||||
} else {
|
||||
uiService.setCursorStyleOverride('url("crosshair.png") 7 7, default');
|
||||
userInteraction.setCursorStyleOverride('url("crosshair.png") 7 7, default');
|
||||
}
|
||||
|
||||
cursorOverrideActive = !cursorOverrideActive;
|
||||
@@ -125,8 +127,8 @@
|
||||
<div class="tool-bar" class:hidden={!showUtilityBar}>
|
||||
<div class="toolbar-container">
|
||||
<button on:click={() => toggleFullScreen()}>Full Screen</button>
|
||||
<button on:click={() => uiService.ctrlAltDel()}>Ctrl+Alt+Del</button>
|
||||
<button on:click={() => uiService.metaKey()}>
|
||||
<button on:click={() => userInteraction.ctrlAltDel()}>Ctrl+Alt+Del</button>
|
||||
<button on:click={() => userInteraction.metaKey()}>
|
||||
Meta
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 512 512">
|
||||
<title>ionicons-v5_logos</title>
|
||||
@@ -137,7 +139,7 @@
|
||||
</svg>
|
||||
</button>
|
||||
<button on:click={() => toggleCursorKind()}>Toggle cursor kind</button>
|
||||
<button on:click={() => uiService.shutdown()}>Terminate Session</button>
|
||||
<button on:click={() => userInteraction.shutdown()}>Terminate Session</button>
|
||||
<label style="color: white;">
|
||||
<input on:click={(e) => onUnicodeModeChange(e)} type="checkbox" />
|
||||
Unicode keyboard mode
|
||||
|
||||
Reference in New Issue
Block a user