window.ts 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. /**
  5. * Provides APIs to create windows, communicate with other windows and manipulate the current window.
  6. *
  7. * This package is also accessible with `window.__TAURI__.window` when `tauri.conf.json > build > withGlobalTauri` is set to true.
  8. *
  9. * The APIs must be allowlisted on `tauri.conf.json`:
  10. * ```json
  11. * {
  12. * "tauri": {
  13. * "allowlist": {
  14. * "window": {
  15. * "all": true, // enable all window APIs
  16. * "create": true, // enable window creation
  17. * "center": true,
  18. * "requestUserAttention": true,
  19. * "setResizable": true,
  20. * "setTitle": true,
  21. * "maximize": true,
  22. * "unmaximize": true,
  23. * "minimize": true,
  24. * "unminimize": true,
  25. * "show": true,
  26. * "hide": true,
  27. * "close": true,
  28. * "setDecorations": true,
  29. * "setAlwaysOnTop": true,
  30. * "setSize": true,
  31. * "setMinSize": true,
  32. * "setMaxSize": true,
  33. * "setPosition": true,
  34. * "setFullscreen": true,
  35. * "setFocus": true,
  36. * "setIcon": true,
  37. * "setSkipTaskbar": true,
  38. * "setCursorGrab": true,
  39. * "setCursorVisible": true,
  40. * "setCursorIcon": true,
  41. * "setCursorPosition": true,
  42. * "startDragging": true,
  43. * "print": true
  44. * }
  45. * }
  46. * }
  47. * }
  48. * ```
  49. * It is recommended to allowlist only the APIs you use for optimal bundle size and security.
  50. *
  51. * # Window events
  52. *
  53. * Events can be listened using `appWindow.listen`:
  54. * ```typescript
  55. * import { appWindow } from "@tauri-apps/api/window";
  56. * appWindow.listen("my-window-event", ({ event, payload }) => { });
  57. * ```
  58. *
  59. * @module
  60. */
  61. import { invokeTauriCommand } from './helpers/tauri'
  62. import type { EventName, EventCallback, UnlistenFn } from './event'
  63. import { emit, Event, listen, once } from './helpers/event'
  64. type Theme = 'light' | 'dark'
  65. /** Allows you to retrieve information about a given monitor. */
  66. interface Monitor {
  67. /** Human-readable name of the monitor */
  68. name: string | null
  69. /** The monitor's resolution. */
  70. size: PhysicalSize
  71. /** the Top-left corner position of the monitor relative to the larger full screen area. */
  72. position: PhysicalPosition
  73. /** The scale factor that can be used to map physical pixels to logical pixels. */
  74. scaleFactor: number
  75. }
  76. /** The payload for the `scaleChange` event. */
  77. interface ScaleFactorChanged {
  78. /** The new window scale factor. */
  79. scaleFactor: number
  80. /** The new window size */
  81. size: PhysicalSize
  82. }
  83. /** The file drop event types. */
  84. type FileDropEvent =
  85. | { type: 'hover'; paths: string[] }
  86. | { type: 'drop'; paths: string[] }
  87. | { type: 'cancel' }
  88. /** A size represented in logical pixels. */
  89. class LogicalSize {
  90. type = 'Logical'
  91. width: number
  92. height: number
  93. constructor(width: number, height: number) {
  94. this.width = width
  95. this.height = height
  96. }
  97. }
  98. /** A size represented in physical pixels. */
  99. class PhysicalSize {
  100. type = 'Physical'
  101. width: number
  102. height: number
  103. constructor(width: number, height: number) {
  104. this.width = width
  105. this.height = height
  106. }
  107. /**
  108. * Converts the physical size to a logical one.
  109. * @example
  110. * ```typescript
  111. * import { appWindow } from '@tauri-apps/api/window';
  112. * const factor = await appWindow.scaleFactor();
  113. * const size = await appWindow.innerSize();
  114. * const logical = size.toLogical(factor);
  115. * ```
  116. * */
  117. toLogical(scaleFactor: number): LogicalSize {
  118. return new LogicalSize(this.width / scaleFactor, this.height / scaleFactor)
  119. }
  120. }
  121. /** A position represented in logical pixels. */
  122. class LogicalPosition {
  123. type = 'Logical'
  124. x: number
  125. y: number
  126. constructor(x: number, y: number) {
  127. this.x = x
  128. this.y = y
  129. }
  130. }
  131. /** A position represented in physical pixels. */
  132. class PhysicalPosition {
  133. type = 'Physical'
  134. x: number
  135. y: number
  136. constructor(x: number, y: number) {
  137. this.x = x
  138. this.y = y
  139. }
  140. /**
  141. * Converts the physical position to a logical one.
  142. * @example
  143. * ```typescript
  144. * import { appWindow } from '@tauri-apps/api/window';
  145. * const factor = await appWindow.scaleFactor();
  146. * const position = await appWindow.innerPosition();
  147. * const logical = position.toLogical(factor);
  148. * ```
  149. * */
  150. toLogical(scaleFactor: number): LogicalPosition {
  151. return new LogicalPosition(this.x / scaleFactor, this.y / scaleFactor)
  152. }
  153. }
  154. /** @ignore */
  155. interface WindowDef {
  156. label: string
  157. }
  158. /** @ignore */
  159. declare global {
  160. interface Window {
  161. __TAURI_METADATA__: {
  162. __windows: WindowDef[]
  163. __currentWindow: WindowDef
  164. }
  165. }
  166. }
  167. /** Attention type to request on a window. */
  168. enum UserAttentionType {
  169. /**
  170. * #### Platform-specific
  171. * - **macOS:** Bounces the dock icon until the application is in focus.
  172. * - **Windows:** Flashes both the window and the taskbar button until the application is in focus.
  173. */
  174. Critical = 1,
  175. /**
  176. * #### Platform-specific
  177. * - **macOS:** Bounces the dock icon once.
  178. * - **Windows:** Flashes the taskbar button until the application is in focus.
  179. */
  180. Informational
  181. }
  182. export type CursorIcon =
  183. | 'default'
  184. | 'crosshair'
  185. | 'hand'
  186. | 'arrow'
  187. | 'move'
  188. | 'text'
  189. | 'wait'
  190. | 'help'
  191. | 'progress'
  192. // something cannot be done
  193. | 'notAllowed'
  194. | 'contextMenu'
  195. | 'cell'
  196. | 'verticalText'
  197. | 'alias'
  198. | 'copy'
  199. | 'noDrop'
  200. // something can be grabbed
  201. | 'grab'
  202. /// something is grabbed
  203. | 'grabbing'
  204. | 'allScroll'
  205. | 'zoomIn'
  206. | 'zoomOut'
  207. // edge is to be moved
  208. | 'eResize'
  209. | 'nResize'
  210. | 'neResize'
  211. | 'nwResize'
  212. | 'sResize'
  213. | 'seResize'
  214. | 'swResize'
  215. | 'wResize'
  216. | 'ewResize'
  217. | 'nsResize'
  218. | 'neswResize'
  219. | 'nwseResize'
  220. | 'colResize'
  221. | 'rowResize'
  222. /**
  223. * Get an instance of `WebviewWindow` for the current webview window.
  224. *
  225. * @return The current WebviewWindow.
  226. */
  227. function getCurrent(): WebviewWindow {
  228. return new WebviewWindow(window.__TAURI_METADATA__.__currentWindow.label, {
  229. // @ts-expect-error
  230. skip: true
  231. })
  232. }
  233. /**
  234. * Gets an instance of `WebviewWindow` for all available webview windows.
  235. *
  236. * @return The list of WebviewWindow.
  237. */
  238. function getAll(): WebviewWindow[] {
  239. return window.__TAURI_METADATA__.__windows.map(
  240. (w) =>
  241. new WebviewWindow(w.label, {
  242. // @ts-expect-error
  243. skip: true
  244. })
  245. )
  246. }
  247. /** @ignore */
  248. // events that are emitted right here instead of by the created webview
  249. const localTauriEvents = ['tauri://created', 'tauri://error']
  250. /** @ignore */
  251. export type WindowLabel = string
  252. /**
  253. * A webview window handle allows emitting and listening to events from the backend that are tied to the window.
  254. */
  255. class WebviewWindowHandle {
  256. /** The window label. It is a unique identifier for the window, can be used to reference it later. */
  257. label: WindowLabel
  258. /** Local event listeners. */
  259. listeners: { [key: string]: Array<EventCallback<any>> }
  260. constructor(label: WindowLabel) {
  261. this.label = label
  262. // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
  263. this.listeners = Object.create(null)
  264. }
  265. /**
  266. * Listen to an event emitted by the backend that is tied to the webview window.
  267. *
  268. * @example
  269. * ```typescript
  270. * import { appWindow } from '@tauri-apps/api/window';
  271. * const unlisten = await appWindow.listen<string>('state-changed', (event) => {
  272. * console.log(`Got error: ${payload}`);
  273. * });
  274. *
  275. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  276. * unlisten();
  277. * ```
  278. *
  279. * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
  280. * @param handler Event handler.
  281. * @returns A promise resolving to a function to unlisten to the event.
  282. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  283. */
  284. async listen<T>(
  285. event: EventName,
  286. handler: EventCallback<T>
  287. ): Promise<UnlistenFn> {
  288. if (this._handleTauriEvent(event, handler)) {
  289. return Promise.resolve(() => {
  290. // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, security/detect-object-injection
  291. const listeners = this.listeners[event]
  292. listeners.splice(listeners.indexOf(handler), 1)
  293. })
  294. }
  295. return listen(event, this.label, handler)
  296. }
  297. /**
  298. * Listen to an one-off event emitted by the backend that is tied to the webview window.
  299. *
  300. * @example
  301. * ```typescript
  302. * import { appWindow } from '@tauri-apps/api/window';
  303. * const unlisten = await appWindow.once<null>('initialized', (event) => {
  304. * console.log(`Window initialized!`);
  305. * });
  306. *
  307. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  308. * unlisten();
  309. * ```
  310. *
  311. * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
  312. * @param handler Event handler.
  313. * @returns A promise resolving to a function to unlisten to the event.
  314. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  315. */
  316. async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
  317. if (this._handleTauriEvent(event, handler)) {
  318. return Promise.resolve(() => {
  319. // eslint-disable-next-line security/detect-object-injection
  320. const listeners = this.listeners[event]
  321. listeners.splice(listeners.indexOf(handler), 1)
  322. })
  323. }
  324. return once(event, this.label, handler)
  325. }
  326. /**
  327. * Emits an event to the backend, tied to the webview window.
  328. * @example
  329. * ```typescript
  330. * import { appWindow } from '@tauri-apps/api/window';
  331. * await appWindow.emit('window-loaded', { loggedIn: true, token: 'authToken' });
  332. * ```
  333. *
  334. * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
  335. * @param payload Event payload.
  336. */
  337. async emit(event: string, payload?: unknown): Promise<void> {
  338. if (localTauriEvents.includes(event)) {
  339. // eslint-disable-next-line
  340. for (const handler of this.listeners[event] || []) {
  341. handler({ event, id: -1, windowLabel: this.label, payload })
  342. }
  343. return Promise.resolve()
  344. }
  345. return emit(event, this.label, payload)
  346. }
  347. _handleTauriEvent<T>(event: string, handler: EventCallback<T>): boolean {
  348. if (localTauriEvents.includes(event)) {
  349. if (!(event in this.listeners)) {
  350. // eslint-disable-next-line
  351. this.listeners[event] = [handler]
  352. } else {
  353. // eslint-disable-next-line
  354. this.listeners[event].push(handler)
  355. }
  356. return true
  357. }
  358. return false
  359. }
  360. }
  361. /**
  362. * Manage the current window object.
  363. */
  364. class WindowManager extends WebviewWindowHandle {
  365. // Getters
  366. /**
  367. * The scale factor that can be used to map physical pixels to logical pixels.
  368. * @example
  369. * ```typescript
  370. * import { appWindow } from '@tauri-apps/api/window';
  371. * const factor = await appWindow.scaleFactor();
  372. * ```
  373. *
  374. * @returns The window's monitor scale factor.
  375. * */
  376. async scaleFactor(): Promise<number> {
  377. return invokeTauriCommand({
  378. __tauriModule: 'Window',
  379. message: {
  380. cmd: 'manage',
  381. data: {
  382. label: this.label,
  383. cmd: {
  384. type: 'scaleFactor'
  385. }
  386. }
  387. }
  388. })
  389. }
  390. /**
  391. * The position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop.
  392. * @example
  393. * ```typescript
  394. * import { appWindow } from '@tauri-apps/api/window';
  395. * const position = await appWindow.innerPosition();
  396. * ```
  397. *
  398. * @returns The window's inner position.
  399. * */
  400. async innerPosition(): Promise<PhysicalPosition> {
  401. return invokeTauriCommand<{ x: number; y: number }>({
  402. __tauriModule: 'Window',
  403. message: {
  404. cmd: 'manage',
  405. data: {
  406. label: this.label,
  407. cmd: {
  408. type: 'innerPosition'
  409. }
  410. }
  411. }
  412. }).then(({ x, y }) => new PhysicalPosition(x, y))
  413. }
  414. /**
  415. * The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.
  416. * @example
  417. * ```typescript
  418. * import { appWindow } from '@tauri-apps/api/window';
  419. * const position = await appWindow.outerPosition();
  420. * ```
  421. *
  422. * @returns The window's outer position.
  423. * */
  424. async outerPosition(): Promise<PhysicalPosition> {
  425. return invokeTauriCommand<{ x: number; y: number }>({
  426. __tauriModule: 'Window',
  427. message: {
  428. cmd: 'manage',
  429. data: {
  430. label: this.label,
  431. cmd: {
  432. type: 'outerPosition'
  433. }
  434. }
  435. }
  436. }).then(({ x, y }) => new PhysicalPosition(x, y))
  437. }
  438. /**
  439. * The physical size of the window's client area.
  440. * The client area is the content of the window, excluding the title bar and borders.
  441. * @example
  442. * ```typescript
  443. * import { appWindow } from '@tauri-apps/api/window';
  444. * const size = await appWindow.innerSize();
  445. * ```
  446. *
  447. * @returns The window's inner size.
  448. */
  449. async innerSize(): Promise<PhysicalSize> {
  450. return invokeTauriCommand<{ width: number; height: number }>({
  451. __tauriModule: 'Window',
  452. message: {
  453. cmd: 'manage',
  454. data: {
  455. label: this.label,
  456. cmd: {
  457. type: 'innerSize'
  458. }
  459. }
  460. }
  461. }).then(({ width, height }) => new PhysicalSize(width, height))
  462. }
  463. /**
  464. * The physical size of the entire window.
  465. * These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead.
  466. * @example
  467. * ```typescript
  468. * import { appWindow } from '@tauri-apps/api/window';
  469. * const size = await appWindow.outerSize();
  470. * ```
  471. *
  472. * @returns The window's outer size.
  473. */
  474. async outerSize(): Promise<PhysicalSize> {
  475. return invokeTauriCommand<{ width: number; height: number }>({
  476. __tauriModule: 'Window',
  477. message: {
  478. cmd: 'manage',
  479. data: {
  480. label: this.label,
  481. cmd: {
  482. type: 'outerSize'
  483. }
  484. }
  485. }
  486. }).then(({ width, height }) => new PhysicalSize(width, height))
  487. }
  488. /**
  489. * Gets the window's current fullscreen state.
  490. * @example
  491. * ```typescript
  492. * import { appWindow } from '@tauri-apps/api/window';
  493. * const fullscreen = await appWindow.isFullscreen();
  494. * ```
  495. *
  496. * @returns Whether the window is in fullscreen mode or not.
  497. * */
  498. async isFullscreen(): Promise<boolean> {
  499. return invokeTauriCommand({
  500. __tauriModule: 'Window',
  501. message: {
  502. cmd: 'manage',
  503. data: {
  504. label: this.label,
  505. cmd: {
  506. type: 'isFullscreen'
  507. }
  508. }
  509. }
  510. })
  511. }
  512. /**
  513. * Gets the window's current maximized state.
  514. * @example
  515. * ```typescript
  516. * import { appWindow } from '@tauri-apps/api/window';
  517. * const maximized = await appWindow.isMaximized();
  518. * ```
  519. *
  520. * @returns Whether the window is maximized or not.
  521. * */
  522. async isMaximized(): Promise<boolean> {
  523. return invokeTauriCommand({
  524. __tauriModule: 'Window',
  525. message: {
  526. cmd: 'manage',
  527. data: {
  528. label: this.label,
  529. cmd: {
  530. type: 'isMaximized'
  531. }
  532. }
  533. }
  534. })
  535. }
  536. /**
  537. * Gets the window's current decorated state.
  538. * @example
  539. * ```typescript
  540. * import { appWindow } from '@tauri-apps/api/window';
  541. * const decorated = await appWindow.isDecorated();
  542. * ```
  543. *
  544. * @returns Whether the window is decorated or not.
  545. * */
  546. async isDecorated(): Promise<boolean> {
  547. return invokeTauriCommand({
  548. __tauriModule: 'Window',
  549. message: {
  550. cmd: 'manage',
  551. data: {
  552. label: this.label,
  553. cmd: {
  554. type: 'isDecorated'
  555. }
  556. }
  557. }
  558. })
  559. }
  560. /**
  561. * Gets the window's current resizable state.
  562. * @example
  563. * ```typescript
  564. * import { appWindow } from '@tauri-apps/api/window';
  565. * const resizable = await appWindow.isResizable();
  566. * ```
  567. *
  568. * @returns Whether the window is resizable or not.
  569. * */
  570. async isResizable(): Promise<boolean> {
  571. return invokeTauriCommand({
  572. __tauriModule: 'Window',
  573. message: {
  574. cmd: 'manage',
  575. data: {
  576. label: this.label,
  577. cmd: {
  578. type: 'isResizable'
  579. }
  580. }
  581. }
  582. })
  583. }
  584. /**
  585. * Gets the window's current visible state.
  586. * @example
  587. * ```typescript
  588. * import { appWindow } from '@tauri-apps/api/window';
  589. * const visible = await appWindow.isVisible();
  590. * ```
  591. *
  592. * @returns Whether the window is visible or not.
  593. * */
  594. async isVisible(): Promise<boolean> {
  595. return invokeTauriCommand({
  596. __tauriModule: 'Window',
  597. message: {
  598. cmd: 'manage',
  599. data: {
  600. label: this.label,
  601. cmd: {
  602. type: 'isVisible'
  603. }
  604. }
  605. }
  606. })
  607. }
  608. /**
  609. * Gets the window's current theme.
  610. *
  611. * #### Platform-specific
  612. *
  613. * - **Linux:** Not implemented, always returns `light`.
  614. * - **macOS:** Theme was introduced on macOS 10.14. Returns `light` on macOS 10.13 and below.
  615. *
  616. * @example
  617. * ```typescript
  618. * import { appWindow } from '@tauri-apps/api/window';
  619. * const theme = await appWindow.theme();
  620. * ```
  621. *
  622. * @returns The window theme.
  623. * */
  624. async theme(): Promise<Theme | null> {
  625. return invokeTauriCommand({
  626. __tauriModule: 'Window',
  627. message: {
  628. cmd: 'manage',
  629. data: {
  630. label: this.label,
  631. cmd: {
  632. type: 'theme'
  633. }
  634. }
  635. }
  636. })
  637. }
  638. // Setters
  639. /**
  640. * Centers the window.
  641. * @example
  642. * ```typescript
  643. * import { appWindow } from '@tauri-apps/api/window';
  644. * await appWindow.center();
  645. * ```
  646. *
  647. * @param resizable
  648. * @returns A promise indicating the success or failure of the operation.
  649. */
  650. async center(): Promise<void> {
  651. return invokeTauriCommand({
  652. __tauriModule: 'Window',
  653. message: {
  654. cmd: 'manage',
  655. data: {
  656. label: this.label,
  657. cmd: {
  658. type: 'center'
  659. }
  660. }
  661. }
  662. })
  663. }
  664. /**
  665. * Requests user attention to the window, this has no effect if the application
  666. * is already focused. How requesting for user attention manifests is platform dependent,
  667. * see `UserAttentionType` for details.
  668. *
  669. * Providing `null` will unset the request for user attention. Unsetting the request for
  670. * user attention might not be done automatically by the WM when the window receives input.
  671. *
  672. * #### Platform-specific
  673. *
  674. * - **macOS:** `null` has no effect.
  675. * - **Linux:** Urgency levels have the same effect.
  676. * @example
  677. * ```typescript
  678. * import { appWindow } from '@tauri-apps/api/window';
  679. * await appWindow.requestUserAttention();
  680. * ```
  681. *
  682. * @param resizable
  683. * @returns A promise indicating the success or failure of the operation.
  684. */
  685. async requestUserAttention(
  686. requestType: UserAttentionType | null
  687. ): Promise<void> {
  688. let requestType_ = null
  689. if (requestType) {
  690. if (requestType === UserAttentionType.Critical) {
  691. requestType_ = { type: 'Critical' }
  692. } else {
  693. requestType_ = { type: 'Informational' }
  694. }
  695. }
  696. return invokeTauriCommand({
  697. __tauriModule: 'Window',
  698. message: {
  699. cmd: 'manage',
  700. data: {
  701. label: this.label,
  702. cmd: {
  703. type: 'requestUserAttention',
  704. payload: requestType_
  705. }
  706. }
  707. }
  708. })
  709. }
  710. /**
  711. * Updates the window resizable flag.
  712. * @example
  713. * ```typescript
  714. * import { appWindow } from '@tauri-apps/api/window';
  715. * await appWindow.setResizable(false);
  716. * ```
  717. *
  718. * @param resizable
  719. * @returns A promise indicating the success or failure of the operation.
  720. */
  721. async setResizable(resizable: boolean): Promise<void> {
  722. return invokeTauriCommand({
  723. __tauriModule: 'Window',
  724. message: {
  725. cmd: 'manage',
  726. data: {
  727. label: this.label,
  728. cmd: {
  729. type: 'setResizable',
  730. payload: resizable
  731. }
  732. }
  733. }
  734. })
  735. }
  736. /**
  737. * Sets the window title.
  738. * @example
  739. * ```typescript
  740. * import { appWindow } from '@tauri-apps/api/window';
  741. * await appWindow.setTitle('Tauri');
  742. * ```
  743. *
  744. * @param title The new title
  745. * @returns A promise indicating the success or failure of the operation.
  746. */
  747. async setTitle(title: string): Promise<void> {
  748. return invokeTauriCommand({
  749. __tauriModule: 'Window',
  750. message: {
  751. cmd: 'manage',
  752. data: {
  753. label: this.label,
  754. cmd: {
  755. type: 'setTitle',
  756. payload: title
  757. }
  758. }
  759. }
  760. })
  761. }
  762. /**
  763. * Maximizes the window.
  764. * @example
  765. * ```typescript
  766. * import { appWindow } from '@tauri-apps/api/window';
  767. * await appWindow.maximize();
  768. * ```
  769. *
  770. * @returns A promise indicating the success or failure of the operation.
  771. */
  772. async maximize(): Promise<void> {
  773. return invokeTauriCommand({
  774. __tauriModule: 'Window',
  775. message: {
  776. cmd: 'manage',
  777. data: {
  778. label: this.label,
  779. cmd: {
  780. type: 'maximize'
  781. }
  782. }
  783. }
  784. })
  785. }
  786. /**
  787. * Unmaximizes the window.
  788. * @example
  789. * ```typescript
  790. * import { appWindow } from '@tauri-apps/api/window';
  791. * await appWindow.unmaximize();
  792. * ```
  793. *
  794. * @returns A promise indicating the success or failure of the operation.
  795. */
  796. async unmaximize(): Promise<void> {
  797. return invokeTauriCommand({
  798. __tauriModule: 'Window',
  799. message: {
  800. cmd: 'manage',
  801. data: {
  802. label: this.label,
  803. cmd: {
  804. type: 'unmaximize'
  805. }
  806. }
  807. }
  808. })
  809. }
  810. /**
  811. * Toggles the window maximized state.
  812. * @example
  813. * ```typescript
  814. * import { appWindow } from '@tauri-apps/api/window';
  815. * await appWindow.toggleMaximize();
  816. * ```
  817. *
  818. * @returns A promise indicating the success or failure of the operation.
  819. */
  820. async toggleMaximize(): Promise<void> {
  821. return invokeTauriCommand({
  822. __tauriModule: 'Window',
  823. message: {
  824. cmd: 'manage',
  825. data: {
  826. label: this.label,
  827. cmd: {
  828. type: 'toggleMaximize'
  829. }
  830. }
  831. }
  832. })
  833. }
  834. /**
  835. * Minimizes the window.
  836. * @example
  837. * ```typescript
  838. * import { appWindow } from '@tauri-apps/api/window';
  839. * await appWindow.minimize();
  840. * ```
  841. *
  842. * @returns A promise indicating the success or failure of the operation.
  843. */
  844. async minimize(): Promise<void> {
  845. return invokeTauriCommand({
  846. __tauriModule: 'Window',
  847. message: {
  848. cmd: 'manage',
  849. data: {
  850. label: this.label,
  851. cmd: {
  852. type: 'minimize'
  853. }
  854. }
  855. }
  856. })
  857. }
  858. /**
  859. * Unminimizes the window.
  860. * @example
  861. * ```typescript
  862. * import { appWindow } from '@tauri-apps/api/window';
  863. * await appWindow.unminimize();
  864. * ```
  865. *
  866. * @returns A promise indicating the success or failure of the operation.
  867. */
  868. async unminimize(): Promise<void> {
  869. return invokeTauriCommand({
  870. __tauriModule: 'Window',
  871. message: {
  872. cmd: 'manage',
  873. data: {
  874. label: this.label,
  875. cmd: {
  876. type: 'unminimize'
  877. }
  878. }
  879. }
  880. })
  881. }
  882. /**
  883. * Sets the window visibility to true.
  884. * @example
  885. * ```typescript
  886. * import { appWindow } from '@tauri-apps/api/window';
  887. * await appWindow.show();
  888. * ```
  889. *
  890. * @returns A promise indicating the success or failure of the operation.
  891. */
  892. async show(): Promise<void> {
  893. return invokeTauriCommand({
  894. __tauriModule: 'Window',
  895. message: {
  896. cmd: 'manage',
  897. data: {
  898. label: this.label,
  899. cmd: {
  900. type: 'show'
  901. }
  902. }
  903. }
  904. })
  905. }
  906. /**
  907. * Sets the window visibility to false.
  908. * @example
  909. * ```typescript
  910. * import { appWindow } from '@tauri-apps/api/window';
  911. * await appWindow.hide();
  912. * ```
  913. *
  914. * @returns A promise indicating the success or failure of the operation.
  915. */
  916. async hide(): Promise<void> {
  917. return invokeTauriCommand({
  918. __tauriModule: 'Window',
  919. message: {
  920. cmd: 'manage',
  921. data: {
  922. label: this.label,
  923. cmd: {
  924. type: 'hide'
  925. }
  926. }
  927. }
  928. })
  929. }
  930. /**
  931. * Closes the window.
  932. * @example
  933. * ```typescript
  934. * import { appWindow } from '@tauri-apps/api/window';
  935. * await appWindow.close();
  936. * ```
  937. *
  938. * @returns A promise indicating the success or failure of the operation.
  939. */
  940. async close(): Promise<void> {
  941. return invokeTauriCommand({
  942. __tauriModule: 'Window',
  943. message: {
  944. cmd: 'manage',
  945. data: {
  946. label: this.label,
  947. cmd: {
  948. type: 'close'
  949. }
  950. }
  951. }
  952. })
  953. }
  954. /**
  955. * Whether the window should have borders and bars.
  956. * @example
  957. * ```typescript
  958. * import { appWindow } from '@tauri-apps/api/window';
  959. * await appWindow.setDecorations(false);
  960. * ```
  961. *
  962. * @param decorations Whether the window should have borders and bars.
  963. * @returns A promise indicating the success or failure of the operation.
  964. */
  965. async setDecorations(decorations: boolean): Promise<void> {
  966. return invokeTauriCommand({
  967. __tauriModule: 'Window',
  968. message: {
  969. cmd: 'manage',
  970. data: {
  971. label: this.label,
  972. cmd: {
  973. type: 'setDecorations',
  974. payload: decorations
  975. }
  976. }
  977. }
  978. })
  979. }
  980. /**
  981. * Whether the window should always be on top of other windows.
  982. * @example
  983. * ```typescript
  984. * import { appWindow } from '@tauri-apps/api/window';
  985. * await appWindow.setAlwaysOnTop(true);
  986. * ```
  987. *
  988. * @param alwaysOnTop Whether the window should always be on top of other windows or not.
  989. * @returns A promise indicating the success or failure of the operation.
  990. */
  991. async setAlwaysOnTop(alwaysOnTop: boolean): Promise<void> {
  992. return invokeTauriCommand({
  993. __tauriModule: 'Window',
  994. message: {
  995. cmd: 'manage',
  996. data: {
  997. label: this.label,
  998. cmd: {
  999. type: 'setAlwaysOnTop',
  1000. payload: alwaysOnTop
  1001. }
  1002. }
  1003. }
  1004. })
  1005. }
  1006. /**
  1007. * Resizes the window with a new inner size.
  1008. * @example
  1009. * ```typescript
  1010. * import { appWindow, LogicalSize } from '@tauri-apps/api/window';
  1011. * await appWindow.setSize(new LogicalSize(600, 500));
  1012. * ```
  1013. *
  1014. * @param size The logical or physical inner size.
  1015. * @returns A promise indicating the success or failure of the operation.
  1016. */
  1017. async setSize(size: LogicalSize | PhysicalSize): Promise<void> {
  1018. if (!size || (size.type !== 'Logical' && size.type !== 'Physical')) {
  1019. throw new Error(
  1020. 'the `size` argument must be either a LogicalSize or a PhysicalSize instance'
  1021. )
  1022. }
  1023. return invokeTauriCommand({
  1024. __tauriModule: 'Window',
  1025. message: {
  1026. cmd: 'manage',
  1027. data: {
  1028. label: this.label,
  1029. cmd: {
  1030. type: 'setSize',
  1031. payload: {
  1032. type: size.type,
  1033. data: {
  1034. width: size.width,
  1035. height: size.height
  1036. }
  1037. }
  1038. }
  1039. }
  1040. }
  1041. })
  1042. }
  1043. /**
  1044. * Sets the window minimum inner size. If the `size` argument is not provided, the constraint is unset.
  1045. * @example
  1046. * ```typescript
  1047. * import { appWindow, PhysicalSize } from '@tauri-apps/api/window';
  1048. * await appWindow.setMinSize(new PhysicalSize(600, 500));
  1049. * ```
  1050. *
  1051. * @param size The logical or physical inner size, or `null` to unset the constraint.
  1052. * @returns A promise indicating the success or failure of the operation.
  1053. */
  1054. async setMinSize(
  1055. size: LogicalSize | PhysicalSize | null | undefined
  1056. ): Promise<void> {
  1057. if (size && size.type !== 'Logical' && size.type !== 'Physical') {
  1058. throw new Error(
  1059. 'the `size` argument must be either a LogicalSize or a PhysicalSize instance'
  1060. )
  1061. }
  1062. return invokeTauriCommand({
  1063. __tauriModule: 'Window',
  1064. message: {
  1065. cmd: 'manage',
  1066. data: {
  1067. label: this.label,
  1068. cmd: {
  1069. type: 'setMinSize',
  1070. payload: size
  1071. ? {
  1072. type: size.type,
  1073. data: {
  1074. width: size.width,
  1075. height: size.height
  1076. }
  1077. }
  1078. : null
  1079. }
  1080. }
  1081. }
  1082. })
  1083. }
  1084. /**
  1085. * Sets the window maximum inner size. If the `size` argument is undefined, the constraint is unset.
  1086. * @example
  1087. * ```typescript
  1088. * import { appWindow, LogicalSize } from '@tauri-apps/api/window';
  1089. * await appWindow.setMaxSize(new LogicalSize(600, 500));
  1090. * ```
  1091. *
  1092. * @param size The logical or physical inner size, or `null` to unset the constraint.
  1093. * @returns A promise indicating the success or failure of the operation.
  1094. */
  1095. async setMaxSize(
  1096. size: LogicalSize | PhysicalSize | null | undefined
  1097. ): Promise<void> {
  1098. if (size && size.type !== 'Logical' && size.type !== 'Physical') {
  1099. throw new Error(
  1100. 'the `size` argument must be either a LogicalSize or a PhysicalSize instance'
  1101. )
  1102. }
  1103. return invokeTauriCommand({
  1104. __tauriModule: 'Window',
  1105. message: {
  1106. cmd: 'manage',
  1107. data: {
  1108. label: this.label,
  1109. cmd: {
  1110. type: 'setMaxSize',
  1111. payload: size
  1112. ? {
  1113. type: size.type,
  1114. data: {
  1115. width: size.width,
  1116. height: size.height
  1117. }
  1118. }
  1119. : null
  1120. }
  1121. }
  1122. }
  1123. })
  1124. }
  1125. /**
  1126. * Sets the window outer position.
  1127. * @example
  1128. * ```typescript
  1129. * import { appWindow, LogicalPosition } from '@tauri-apps/api/window';
  1130. * await appWindow.setPosition(new LogicalPosition(600, 500));
  1131. * ```
  1132. *
  1133. * @param position The new position, in logical or physical pixels.
  1134. * @returns A promise indicating the success or failure of the operation.
  1135. */
  1136. async setPosition(
  1137. position: LogicalPosition | PhysicalPosition
  1138. ): Promise<void> {
  1139. if (
  1140. !position ||
  1141. (position.type !== 'Logical' && position.type !== 'Physical')
  1142. ) {
  1143. throw new Error(
  1144. 'the `position` argument must be either a LogicalPosition or a PhysicalPosition instance'
  1145. )
  1146. }
  1147. return invokeTauriCommand({
  1148. __tauriModule: 'Window',
  1149. message: {
  1150. cmd: 'manage',
  1151. data: {
  1152. label: this.label,
  1153. cmd: {
  1154. type: 'setPosition',
  1155. payload: {
  1156. type: position.type,
  1157. data: {
  1158. x: position.x,
  1159. y: position.y
  1160. }
  1161. }
  1162. }
  1163. }
  1164. }
  1165. })
  1166. }
  1167. /**
  1168. * Sets the window fullscreen state.
  1169. * @example
  1170. * ```typescript
  1171. * import { appWindow } from '@tauri-apps/api/window';
  1172. * await appWindow.setFullscreen(true);
  1173. * ```
  1174. *
  1175. * @param fullscreen Whether the window should go to fullscreen or not.
  1176. * @returns A promise indicating the success or failure of the operation.
  1177. */
  1178. async setFullscreen(fullscreen: boolean): Promise<void> {
  1179. return invokeTauriCommand({
  1180. __tauriModule: 'Window',
  1181. message: {
  1182. cmd: 'manage',
  1183. data: {
  1184. label: this.label,
  1185. cmd: {
  1186. type: 'setFullscreen',
  1187. payload: fullscreen
  1188. }
  1189. }
  1190. }
  1191. })
  1192. }
  1193. /**
  1194. * Bring the window to front and focus.
  1195. * @example
  1196. * ```typescript
  1197. * import { appWindow } from '@tauri-apps/api/window';
  1198. * await appWindow.setFocus();
  1199. * ```
  1200. *
  1201. * @returns A promise indicating the success or failure of the operation.
  1202. */
  1203. async setFocus(): Promise<void> {
  1204. return invokeTauriCommand({
  1205. __tauriModule: 'Window',
  1206. message: {
  1207. cmd: 'manage',
  1208. data: {
  1209. label: this.label,
  1210. cmd: {
  1211. type: 'setFocus'
  1212. }
  1213. }
  1214. }
  1215. })
  1216. }
  1217. /**
  1218. * Sets the window icon.
  1219. * @example
  1220. * ```typescript
  1221. * import { appWindow } from '@tauri-apps/api/window';
  1222. * await appWindow.setIcon('/tauri/awesome.png');
  1223. * ```
  1224. *
  1225. * Note that you need the `icon-ico` or `icon-png` Cargo features to use this API.
  1226. * To enable it, change your Cargo.toml file:
  1227. * ```toml
  1228. * [dependencies]
  1229. * tauri = { version = "...", features = ["...", "icon-png"] }
  1230. * ```
  1231. *
  1232. * @param icon Icon bytes or path to the icon file.
  1233. * @returns A promise indicating the success or failure of the operation.
  1234. */
  1235. async setIcon(icon: string | Uint8Array): Promise<void> {
  1236. return invokeTauriCommand({
  1237. __tauriModule: 'Window',
  1238. message: {
  1239. cmd: 'manage',
  1240. data: {
  1241. label: this.label,
  1242. cmd: {
  1243. type: 'setIcon',
  1244. payload: {
  1245. // correctly serialize Uint8Arrays
  1246. icon: typeof icon === 'string' ? icon : Array.from(icon)
  1247. }
  1248. }
  1249. }
  1250. }
  1251. })
  1252. }
  1253. /**
  1254. * Whether to show the window icon in the task bar or not.
  1255. * @example
  1256. * ```typescript
  1257. * import { appWindow } from '@tauri-apps/api/window';
  1258. * await appWindow.setSkipTaskbar(true);
  1259. * ```
  1260. *
  1261. * @param skip true to hide window icon, false to show it.
  1262. * @returns A promise indicating the success or failure of the operation.
  1263. */
  1264. async setSkipTaskbar(skip: boolean): Promise<void> {
  1265. return invokeTauriCommand({
  1266. __tauriModule: 'Window',
  1267. message: {
  1268. cmd: 'manage',
  1269. data: {
  1270. label: this.label,
  1271. cmd: {
  1272. type: 'setSkipTaskbar',
  1273. payload: skip
  1274. }
  1275. }
  1276. }
  1277. })
  1278. }
  1279. /**
  1280. * Grabs the cursor, preventing it from leaving the window.
  1281. *
  1282. * There's no guarantee that the cursor will be hidden. You should
  1283. * hide it by yourself if you want so.
  1284. *
  1285. * #### Platform-specific
  1286. *
  1287. * - **Linux:** Unsupported.
  1288. * - **macOS:** This locks the cursor in a fixed location, which looks visually awkward.
  1289. * @example
  1290. * ```typescript
  1291. * import { appWindow } from '@tauri-apps/api/window';
  1292. * await appWindow.setCursorGrab(true);
  1293. * ```
  1294. *
  1295. * @param grab `true` to grab the cursor icon, `false` to release it.
  1296. * @returns A promise indicating the success or failure of the operation.
  1297. */
  1298. async setCursorGrab(grab: boolean): Promise<void> {
  1299. return invokeTauriCommand({
  1300. __tauriModule: 'Window',
  1301. message: {
  1302. cmd: 'manage',
  1303. data: {
  1304. label: this.label,
  1305. cmd: {
  1306. type: 'setCursorGrab',
  1307. payload: grab
  1308. }
  1309. }
  1310. }
  1311. })
  1312. }
  1313. /**
  1314. * Modifies the cursor's visibility.
  1315. *
  1316. * #### Platform-specific
  1317. *
  1318. * - **Windows:** The cursor is only hidden within the confines of the window.
  1319. * - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
  1320. * outside of the window.
  1321. * @example
  1322. * ```typescript
  1323. * import { appWindow } from '@tauri-apps/api/window';
  1324. * await appWindow.setCursorVisible(false);
  1325. * ```
  1326. *
  1327. * @param visible If `false`, this will hide the cursor. If `true`, this will show the cursor.
  1328. * @returns A promise indicating the success or failure of the operation.
  1329. */
  1330. async setCursorVisible(visible: boolean): Promise<void> {
  1331. return invokeTauriCommand({
  1332. __tauriModule: 'Window',
  1333. message: {
  1334. cmd: 'manage',
  1335. data: {
  1336. label: this.label,
  1337. cmd: {
  1338. type: 'setCursorVisible',
  1339. payload: visible
  1340. }
  1341. }
  1342. }
  1343. })
  1344. }
  1345. /**
  1346. * Modifies the cursor icon of the window.
  1347. * @example
  1348. * ```typescript
  1349. * import { appWindow } from '@tauri-apps/api/window';
  1350. * await appWindow.setCursorIcon('help');
  1351. * ```
  1352. *
  1353. * @param icon The new cursor icon.
  1354. * @returns A promise indicating the success or failure of the operation.
  1355. */
  1356. async setCursorIcon(icon: CursorIcon): Promise<void> {
  1357. return invokeTauriCommand({
  1358. __tauriModule: 'Window',
  1359. message: {
  1360. cmd: 'manage',
  1361. data: {
  1362. label: this.label,
  1363. cmd: {
  1364. type: 'setCursorIcon',
  1365. payload: icon
  1366. }
  1367. }
  1368. }
  1369. })
  1370. }
  1371. /**
  1372. * Changes the position of the cursor in window coordinates.
  1373. * @example
  1374. * ```typescript
  1375. * import { appWindow, LogicalPosition } from '@tauri-apps/api/window';
  1376. * await appWindow.setCursorPosition(new LogicalPosition(600, 300));
  1377. * ```
  1378. *
  1379. * @param position The new cursor position.
  1380. * @returns A promise indicating the success or failure of the operation.
  1381. */
  1382. async setCursorPosition(
  1383. position: LogicalPosition | PhysicalPosition
  1384. ): Promise<void> {
  1385. if (
  1386. !position ||
  1387. (position.type !== 'Logical' && position.type !== 'Physical')
  1388. ) {
  1389. throw new Error(
  1390. 'the `position` argument must be either a LogicalPosition or a PhysicalPosition instance'
  1391. )
  1392. }
  1393. return invokeTauriCommand({
  1394. __tauriModule: 'Window',
  1395. message: {
  1396. cmd: 'manage',
  1397. data: {
  1398. label: this.label,
  1399. cmd: {
  1400. type: 'setCursorPosition',
  1401. payload: {
  1402. type: position.type,
  1403. data: {
  1404. x: position.x,
  1405. y: position.y
  1406. }
  1407. }
  1408. }
  1409. }
  1410. }
  1411. })
  1412. }
  1413. /**
  1414. * Starts dragging the window.
  1415. * @example
  1416. * ```typescript
  1417. * import { appWindow } from '@tauri-apps/api/window';
  1418. * await appWindow.startDragging();
  1419. * ```
  1420. *
  1421. * @return A promise indicating the success or failure of the operation.
  1422. */
  1423. async startDragging(): Promise<void> {
  1424. return invokeTauriCommand({
  1425. __tauriModule: 'Window',
  1426. message: {
  1427. cmd: 'manage',
  1428. data: {
  1429. label: this.label,
  1430. cmd: {
  1431. type: 'startDragging'
  1432. }
  1433. }
  1434. }
  1435. })
  1436. }
  1437. // Listeners
  1438. /**
  1439. * Listen to window resize.
  1440. *
  1441. * @example
  1442. * ```typescript
  1443. * import { appWindow } from "@tauri-apps/api/window";
  1444. * const unlisten = await appWindow.onResized(({ payload: size }) => {
  1445. * console.log('Window resized', size);
  1446. * });
  1447. *
  1448. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1449. * unlisten();
  1450. * ```
  1451. *
  1452. * @param handler
  1453. * @returns A promise resolving to a function to unlisten to the event.
  1454. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1455. */
  1456. async onResized(handler: EventCallback<PhysicalSize>): Promise<UnlistenFn> {
  1457. return this.listen<PhysicalSize>('tauri://resize', handler)
  1458. }
  1459. /**
  1460. * Listen to window move.
  1461. *
  1462. * @example
  1463. * ```typescript
  1464. * import { appWindow } from "@tauri-apps/api/window";
  1465. * const unlisten = await appWindow.onMoved(({ payload: position }) => {
  1466. * console.log('Window moved', position);
  1467. * });
  1468. *
  1469. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1470. * unlisten();
  1471. * ```
  1472. *
  1473. * @param handler
  1474. * @returns A promise resolving to a function to unlisten to the event.
  1475. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1476. */
  1477. async onMoved(handler: EventCallback<PhysicalPosition>): Promise<UnlistenFn> {
  1478. return this.listen<PhysicalPosition>('tauri://move', handler)
  1479. }
  1480. /**
  1481. * Listen to window close requested. Emitted when the user requests to closes the window.
  1482. *
  1483. * @example
  1484. * ```typescript
  1485. * import { appWindow } from "@tauri-apps/api/window";
  1486. * import { confirm } from '@tauri-apps/api/dialog';
  1487. * const unlisten = await appWindow.onCloseRequested(async (event) => {
  1488. * const confirmed = await confirm('Are you sure?');
  1489. * if (!confirmed) {
  1490. * // user did not confirm closing the window; let's prevent it
  1491. * event.preventDefault();
  1492. * }
  1493. * });
  1494. *
  1495. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1496. * unlisten();
  1497. * ```
  1498. *
  1499. * @param handler
  1500. * @returns A promise resolving to a function to unlisten to the event.
  1501. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1502. */
  1503. async onCloseRequested(
  1504. handler: (event: CloseRequestedEvent) => void
  1505. ): Promise<UnlistenFn> {
  1506. return this.listen<null>('tauri://close-requested', (event) => {
  1507. const evt = new CloseRequestedEvent(event)
  1508. void Promise.resolve(handler(evt)).then(() => {
  1509. if (!evt.isPreventDefault()) {
  1510. return this.close()
  1511. }
  1512. })
  1513. })
  1514. }
  1515. /**
  1516. * Listen to window focus change.
  1517. *
  1518. * @example
  1519. * ```typescript
  1520. * import { appWindow } from "@tauri-apps/api/window";
  1521. * const unlisten = await appWindow.onFocusChanged(({ payload: focused }) => {
  1522. * console.log('Focus changed, window is focused? ' + focused);
  1523. * });
  1524. *
  1525. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1526. * unlisten();
  1527. * ```
  1528. *
  1529. * @param handler
  1530. * @returns A promise resolving to a function to unlisten to the event.
  1531. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1532. */
  1533. async onFocusChanged(handler: EventCallback<boolean>): Promise<UnlistenFn> {
  1534. const unlistenFocus = await this.listen<PhysicalPosition>(
  1535. 'tauri://focus',
  1536. (event) => {
  1537. handler({ ...event, payload: true })
  1538. }
  1539. )
  1540. const unlistenBlur = await this.listen<PhysicalPosition>(
  1541. 'tauri://blur',
  1542. (event) => {
  1543. handler({ ...event, payload: false })
  1544. }
  1545. )
  1546. return () => {
  1547. unlistenFocus()
  1548. unlistenBlur()
  1549. }
  1550. }
  1551. /**
  1552. * Listen to window scale change. Emitted when the window's scale factor has changed.
  1553. * The following user actions can cause DPI changes:
  1554. * - Changing the display's resolution.
  1555. * - Changing the display's scale factor (e.g. in Control Panel on Windows).
  1556. * - Moving the window to a display with a different scale factor.
  1557. *
  1558. * @example
  1559. * ```typescript
  1560. * import { appWindow } from "@tauri-apps/api/window";
  1561. * const unlisten = await appWindow.onScaleChanged(({ payload }) => {
  1562. * console.log('Scale changed', payload.scaleFactor, payload.size);
  1563. * });
  1564. *
  1565. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1566. * unlisten();
  1567. * ```
  1568. *
  1569. * @param handler
  1570. * @returns A promise resolving to a function to unlisten to the event.
  1571. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1572. */
  1573. async onScaleChanged(
  1574. handler: EventCallback<ScaleFactorChanged>
  1575. ): Promise<UnlistenFn> {
  1576. return this.listen<ScaleFactorChanged>('tauri://scale-change', handler)
  1577. }
  1578. /**
  1579. * Listen to the window menu item click. The payload is the item id.
  1580. *
  1581. * @example
  1582. * ```typescript
  1583. * import { appWindow } from "@tauri-apps/api/window";
  1584. * const unlisten = await appWindow.onMenuClicked(({ payload: menuId }) => {
  1585. * console.log('Menu clicked: ' + menuId);
  1586. * });
  1587. *
  1588. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1589. * unlisten();
  1590. * ```
  1591. *
  1592. * @param handler
  1593. * @returns A promise resolving to a function to unlisten to the event.
  1594. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1595. */
  1596. async onMenuClicked(handler: EventCallback<string>): Promise<UnlistenFn> {
  1597. return this.listen<string>('tauri://menu', handler)
  1598. }
  1599. /**
  1600. * Listen to a file drop event.
  1601. * The listener is triggered when the user hovers the selected files on the window,
  1602. * drops the files or cancels the operation.
  1603. *
  1604. * @example
  1605. * ```typescript
  1606. * import { appWindow } from "@tauri-apps/api/window";
  1607. * const unlisten = await appWindow.onFileDropEvent((event) => {
  1608. * if (event.payload.type === 'hover') {
  1609. * console.log('User hovering', event.payload.paths);
  1610. * } else if (event.payload.type === 'drop') {
  1611. * console.log('User dropped', event.payload.paths);
  1612. * } else {
  1613. * console.log('File drop cancelled');
  1614. * }
  1615. * });
  1616. *
  1617. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1618. * unlisten();
  1619. * ```
  1620. *
  1621. * @param handler
  1622. * @returns A promise resolving to a function to unlisten to the event.
  1623. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1624. */
  1625. async onFileDropEvent(
  1626. handler: EventCallback<FileDropEvent>
  1627. ): Promise<UnlistenFn> {
  1628. const unlistenFileDrop = await this.listen<string[]>(
  1629. 'tauri://file-drop',
  1630. (event) => {
  1631. handler({ ...event, payload: { type: 'drop', paths: event.payload } })
  1632. }
  1633. )
  1634. const unlistenFileHover = await this.listen<string[]>(
  1635. 'tauri://file-drop-hover',
  1636. (event) => {
  1637. handler({ ...event, payload: { type: 'hover', paths: event.payload } })
  1638. }
  1639. )
  1640. const unlistenCancel = await this.listen<null>(
  1641. 'tauri://file-drop-cancelled',
  1642. (event) => {
  1643. handler({ ...event, payload: { type: 'cancel' } })
  1644. }
  1645. )
  1646. return () => {
  1647. unlistenFileDrop()
  1648. unlistenFileHover()
  1649. unlistenCancel()
  1650. }
  1651. }
  1652. /**
  1653. * Listen to the system theme change.
  1654. *
  1655. * @example
  1656. * ```typescript
  1657. * import { appWindow } from "@tauri-apps/api/window";
  1658. * const unlisten = await appWindow.onThemeChanged(({ payload: theme }) => {
  1659. * console.log('New theme: ' + theme);
  1660. * });
  1661. *
  1662. * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
  1663. * unlisten();
  1664. * ```
  1665. *
  1666. * @param handler
  1667. * @returns A promise resolving to a function to unlisten to the event.
  1668. * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
  1669. */
  1670. async onThemeChanged(handler: EventCallback<Theme>): Promise<UnlistenFn> {
  1671. return this.listen<Theme>('tauri://theme-changed', handler)
  1672. }
  1673. }
  1674. class CloseRequestedEvent {
  1675. /** Event name */
  1676. event: EventName
  1677. /** The label of the window that emitted this event. */
  1678. windowLabel: string
  1679. /** Event identifier used to unlisten */
  1680. id: number
  1681. private _preventDefault = false
  1682. constructor(event: Event<null>) {
  1683. this.event = event.event
  1684. this.windowLabel = event.windowLabel
  1685. this.id = event.id
  1686. }
  1687. preventDefault(): void {
  1688. this._preventDefault = true
  1689. }
  1690. isPreventDefault(): boolean {
  1691. return this._preventDefault
  1692. }
  1693. }
  1694. /**
  1695. * Create new webview windows and get a handle to existing ones.
  1696. *
  1697. * Windows are identified by a *label* a unique identifier that can be used to reference it later.
  1698. * It may only contain alphanumeric characters `a-zA-Z` plus the following special characters `-`, `/`, `:` and `_`.
  1699. *
  1700. * @example
  1701. * ```typescript
  1702. * // loading embedded asset:
  1703. * const webview = new WebviewWindow('theUniqueLabel', {
  1704. * url: 'path/to/page.html'
  1705. * });
  1706. * // alternatively, load a remote URL:
  1707. * const webview = new WebviewWindow('theUniqueLabel', {
  1708. * url: 'https://github.com/tauri-apps/tauri'
  1709. * });
  1710. *
  1711. * webview.once('tauri://created', function () {
  1712. * // webview window successfully created
  1713. * });
  1714. * webview.once('tauri://error', function (e) {
  1715. * // an error happened creating the webview window
  1716. * });
  1717. *
  1718. * // emit an event to the backend
  1719. * await webview.emit("some event", "data");
  1720. * // listen to an event from the backend
  1721. * const unlisten = await webview.listen("event name", e => {});
  1722. * unlisten();
  1723. * ```
  1724. */
  1725. class WebviewWindow extends WindowManager {
  1726. /**
  1727. * Creates a new WebviewWindow.
  1728. * @example
  1729. * ```typescript
  1730. * import { WebviewWindow } from '@tauri-apps/api/window';
  1731. * const webview = new WebviewWindow('my-label', {
  1732. * url: 'https://github.com/tauri-apps/tauri'
  1733. * });
  1734. * webview.once('tauri://created', function () {
  1735. * // webview window successfully created
  1736. * });
  1737. * webview.once('tauri://error', function (e) {
  1738. * // an error happened creating the webview window
  1739. * });
  1740. * ```
  1741. *
  1742. * * @param label The unique webview window label. Must be alphanumeric: `a-zA-Z-/:_`.
  1743. * @returns The WebviewWindow instance to communicate with the webview.
  1744. */
  1745. constructor(label: WindowLabel, options: WindowOptions = {}) {
  1746. super(label)
  1747. // @ts-expect-error
  1748. if (!options?.skip) {
  1749. invokeTauriCommand({
  1750. __tauriModule: 'Window',
  1751. message: {
  1752. cmd: 'createWebview',
  1753. data: {
  1754. options: {
  1755. label,
  1756. ...options
  1757. }
  1758. }
  1759. }
  1760. })
  1761. .then(async () => this.emit('tauri://created'))
  1762. .catch(async (e: string) => this.emit('tauri://error', e))
  1763. }
  1764. }
  1765. /**
  1766. * Gets the WebviewWindow for the webview associated with the given label.
  1767. * @example
  1768. * ```typescript
  1769. * import { WebviewWindow } from '@tauri-apps/api/window';
  1770. * const mainWindow = WebviewWindow.getByLabel('main');
  1771. * ```
  1772. *
  1773. * @param label The webview window label.
  1774. * @returns The WebviewWindow instance to communicate with the webview or null if the webview doesn't exist.
  1775. */
  1776. static getByLabel(label: string): WebviewWindow | null {
  1777. if (getAll().some((w) => w.label === label)) {
  1778. // @ts-expect-error
  1779. return new WebviewWindow(label, { skip: true })
  1780. }
  1781. return null
  1782. }
  1783. }
  1784. /** The WebviewWindow for the current window. */
  1785. let appWindow: WebviewWindow
  1786. if ('__TAURI_METADATA__' in window) {
  1787. appWindow = new WebviewWindow(
  1788. window.__TAURI_METADATA__.__currentWindow.label,
  1789. {
  1790. // @ts-expect-error
  1791. skip: true
  1792. }
  1793. )
  1794. } else {
  1795. console.warn(
  1796. `Could not find "window.__TAURI_METADATA__". The "appWindow" value will reference the "main" window label.\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.`
  1797. )
  1798. appWindow = new WebviewWindow('main', {
  1799. // @ts-expect-error
  1800. skip: true
  1801. })
  1802. }
  1803. /** Configuration for the window to create. */
  1804. interface WindowOptions {
  1805. /**
  1806. * Remote URL or local file path to open.
  1807. *
  1808. * - URL such as `https://github.com/tauri-apps` is opened directly on a Tauri window.
  1809. * - data: URL such as `data:text/html,<html>...` is only supported with the `window-data-url` Cargo feature for the `tauri` dependency.
  1810. * - local file path or route such as `/path/to/page.html` or `/users` is appended to the application URL (the devServer URL on development, or `tauri://localhost/` and `https://tauri.localhost/` on production).
  1811. */
  1812. url?: string
  1813. /** Show window in the center of the screen.. */
  1814. center?: boolean
  1815. /** The initial vertical position. Only applies if `y` is also set. */
  1816. x?: number
  1817. /** The initial horizontal position. Only applies if `x` is also set. */
  1818. y?: number
  1819. /** The initial width. */
  1820. width?: number
  1821. /** The initial height. */
  1822. height?: number
  1823. /** The minimum width. Only applies if `minHeight` is also set. */
  1824. minWidth?: number
  1825. /** The minimum height. Only applies if `minWidth` is also set. */
  1826. minHeight?: number
  1827. /** The maximum width. Only applies if `maxHeight` is also set. */
  1828. maxWidth?: number
  1829. /** The maximum height. Only applies if `maxWidth` is also set. */
  1830. maxHeight?: number
  1831. /** Whether the window is resizable or not. */
  1832. resizable?: boolean
  1833. /** Window title. */
  1834. title?: string
  1835. /** Whether the window is in fullscreen mode or not. */
  1836. fullscreen?: boolean
  1837. /** Whether the window will be initially hidden or focused. */
  1838. focus?: boolean
  1839. /**
  1840. * Whether the window is transparent or not.
  1841. * Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macOSPrivateApi`.
  1842. * WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.
  1843. */
  1844. transparent?: boolean
  1845. /** Whether the window should be maximized upon creation or not. */
  1846. maximized?: boolean
  1847. /** Whether the window should be immediately visible upon creation or not. */
  1848. visible?: boolean
  1849. /** Whether the window should have borders and bars or not. */
  1850. decorations?: boolean
  1851. /** Whether the window should always be on top of other windows or not. */
  1852. alwaysOnTop?: boolean
  1853. /** Whether or not the window icon should be added to the taskbar. */
  1854. skipTaskbar?: boolean
  1855. /**
  1856. * Whether the file drop is enabled or not on the webview. By default it is enabled.
  1857. *
  1858. * Disabling it is required to use drag and drop on the frontend on Windows.
  1859. */
  1860. fileDropEnabled?: boolean
  1861. /**
  1862. * The initial window theme. Defaults to the system theme.
  1863. *
  1864. * Only implemented on Windows and macOS 10.14+.
  1865. */
  1866. theme?: Theme
  1867. }
  1868. /**
  1869. * Returns the monitor on which the window currently resides.
  1870. * Returns `null` if current monitor can't be detected.
  1871. * @example
  1872. * ```typescript
  1873. * import { currentMonitor } from '@tauri-apps/api/window';
  1874. * const monitor = currentMonitor();
  1875. * ```
  1876. */
  1877. async function currentMonitor(): Promise<Monitor | null> {
  1878. return invokeTauriCommand({
  1879. __tauriModule: 'Window',
  1880. message: {
  1881. cmd: 'manage',
  1882. data: {
  1883. cmd: {
  1884. type: 'currentMonitor'
  1885. }
  1886. }
  1887. }
  1888. })
  1889. }
  1890. /**
  1891. * Returns the primary monitor of the system.
  1892. * Returns `null` if it can't identify any monitor as a primary one.
  1893. * @example
  1894. * ```typescript
  1895. * import { primaryMonitor } from '@tauri-apps/api/window';
  1896. * const monitor = primaryMonitor();
  1897. * ```
  1898. */
  1899. async function primaryMonitor(): Promise<Monitor | null> {
  1900. return invokeTauriCommand({
  1901. __tauriModule: 'Window',
  1902. message: {
  1903. cmd: 'manage',
  1904. data: {
  1905. cmd: {
  1906. type: 'primaryMonitor'
  1907. }
  1908. }
  1909. }
  1910. })
  1911. }
  1912. /**
  1913. * Returns the list of all the monitors available on the system.
  1914. * @example
  1915. * ```typescript
  1916. * import { availableMonitors } from '@tauri-apps/api/window';
  1917. * const monitors = availableMonitors();
  1918. * ```
  1919. * */
  1920. async function availableMonitors(): Promise<Monitor[]> {
  1921. return invokeTauriCommand({
  1922. __tauriModule: 'Window',
  1923. message: {
  1924. cmd: 'manage',
  1925. data: {
  1926. cmd: {
  1927. type: 'availableMonitors'
  1928. }
  1929. }
  1930. }
  1931. })
  1932. }
  1933. export {
  1934. WebviewWindow,
  1935. WebviewWindowHandle,
  1936. WindowManager,
  1937. CloseRequestedEvent,
  1938. getCurrent,
  1939. getAll,
  1940. appWindow,
  1941. LogicalSize,
  1942. PhysicalSize,
  1943. LogicalPosition,
  1944. PhysicalPosition,
  1945. UserAttentionType,
  1946. currentMonitor,
  1947. primaryMonitor,
  1948. availableMonitors
  1949. }
  1950. export type { Theme, Monitor, ScaleFactorChanged, FileDropEvent, WindowOptions }