defuss-desktop 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -46,7 +46,9 @@ class WindowManager {
46
46
  windows = [];
47
47
  constructor() {
48
48
  defuss.$(() => {
49
- desktopManager.onResize(defussRuntime.debounce(this.onDesktopResized.bind(this), 50));
49
+ if (desktopManager?.onResize) {
50
+ desktopManager.onResize(defussRuntime.debounce(this.onDesktopResized.bind(this), 50));
51
+ }
50
52
  });
51
53
  }
52
54
  onDesktopResized(dimensions) {
@@ -290,6 +292,11 @@ function Window({
290
292
  }
291
293
  }) {
292
294
  let isDragging = false;
295
+ let dragPointerId = null;
296
+ let dragStartMouse = { x: 0, y: 0 };
297
+ let dragStartWin = { x: 0, y: 0 };
298
+ let lastWin = { x, y };
299
+ let capturedTitleBar = null;
293
300
  const initialWindowState = windowManager.addWindow({
294
301
  id,
295
302
  title,
@@ -301,7 +308,7 @@ function Window({
301
308
  minimizable,
302
309
  maximizable
303
310
  });
304
- let dragStart = { x: initialWindowState.x, y: initialWindowState.y };
311
+ lastWin = { x: initialWindowState.x, y: initialWindowState.y };
305
312
  ref.state = {
306
313
  onClose: () => {
307
314
  console.log("Window closed");
@@ -315,15 +322,9 @@ function Window({
315
322
  console.log("Window maximized");
316
323
  onMaximize();
317
324
  },
318
- minimize: () => {
319
- windowManager.minimizeWindow(initialWindowState.id);
320
- },
321
- maximize: () => {
322
- windowManager.maximizeWindow(initialWindowState.id);
323
- },
324
- restore: () => {
325
- windowManager.restoreWindow(initialWindowState.id);
326
- },
325
+ minimize: () => windowManager.minimizeWindow(initialWindowState.id),
326
+ maximize: () => windowManager.maximizeWindow(initialWindowState.id),
327
+ restore: () => windowManager.restoreWindow(initialWindowState.id),
327
328
  close: () => {
328
329
  console.log("Closing window");
329
330
  windowManager.closeWindow(initialWindowState.id);
@@ -334,45 +335,67 @@ function Window({
334
335
  windowManager.updateWindow(initialWindowState.id, newState);
335
336
  },
336
337
  250
337
- // 1/4 second throttle
338
338
  );
339
- const onMouseMove = async (event) => {
339
+ const onWindowMouseDown = (_event) => windowManager.setActiveWindow(initialWindowState.id);
340
+ const getCurrentWinPos = () => {
341
+ const el = ref.current;
342
+ if (!el) return { x: lastWin.x, y: lastWin.y };
343
+ const left = Number.parseFloat(el.style.left);
344
+ const top = Number.parseFloat(el.style.top);
345
+ return {
346
+ x: Number.isFinite(left) ? left : el.offsetLeft,
347
+ y: Number.isFinite(top) ? top : el.offsetTop
348
+ };
349
+ };
350
+ const stopDragging = (event) => {
340
351
  if (!isDragging) return;
341
- const mouseEvent = event;
342
- const win = await defuss.$(ref);
343
- const deltaX = mouseEvent.clientX - dragStart.x;
344
- const deltaY = mouseEvent.clientY - dragStart.y;
345
- const currentOffset = await win.offset();
346
- if (currentOffset) {
347
- const newX = currentOffset.left + deltaX;
348
- const newY = currentOffset.top + deltaY;
349
- updateWindowState({ x: newX, y: newY });
350
- await win.css({
351
- left: `${newX}px`,
352
- top: `${newY}px`
353
- });
352
+ if (event && capturedTitleBar && typeof capturedTitleBar.releasePointerCapture === "function" && dragPointerId === event.pointerId) {
353
+ try {
354
+ capturedTitleBar.releasePointerCapture(event.pointerId);
355
+ } catch {
356
+ }
354
357
  }
355
- dragStart = { x: mouseEvent.clientX, y: mouseEvent.clientY };
358
+ isDragging = false;
359
+ dragPointerId = null;
360
+ capturedTitleBar = null;
361
+ windowManager.updateWindow(initialWindowState.id, { x: lastWin.x, y: lastWin.y });
356
362
  };
357
- const onWindowMouseDown = (event) => windowManager.setActiveWindow(initialWindowState.id);
358
- const onMouseDown = (event) => {
359
- if (event.target.tagName === "BUTTON") {
360
- isDragging = false;
361
- return;
362
- }
363
+ const onTitlePointerDown = (event) => {
364
+ if (event.pointerType === "mouse" && event.button !== 0) return;
365
+ const target = event.target;
366
+ if (target?.tagName === "BUTTON") return;
367
+ const titleBarEl = target?.closest?.(".title-bar");
368
+ if (!titleBarEl) return;
369
+ windowManager.setActiveWindow(initialWindowState.id);
363
370
  isDragging = true;
364
- dragStart = {
365
- x: event.clientX,
366
- y: event.clientY
367
- };
368
- defuss.$(document).on("mousemove", onMouseMove);
369
- defuss.$(document).on("mouseup", onMouseUp);
371
+ dragPointerId = event.pointerId;
372
+ capturedTitleBar = titleBarEl;
373
+ dragStartMouse = { x: event.clientX, y: event.clientY };
374
+ dragStartWin = getCurrentWinPos();
375
+ if (typeof titleBarEl.setPointerCapture === "function") {
376
+ titleBarEl.setPointerCapture(event.pointerId);
377
+ }
370
378
  event.preventDefault();
371
379
  };
372
- const onMouseUp = () => {
373
- isDragging = false;
374
- defuss.$(document).off("mousemove", onMouseMove);
375
- defuss.$(document).off("mouseup", onMouseUp);
380
+ const onTitlePointerMove = (event) => {
381
+ if (!isDragging) return;
382
+ if (dragPointerId !== null && event.pointerId !== dragPointerId) return;
383
+ const newX = dragStartWin.x + (event.clientX - dragStartMouse.x);
384
+ const newY = dragStartWin.y + (event.clientY - dragStartMouse.y);
385
+ lastWin = { x: newX, y: newY };
386
+ const el = ref.current;
387
+ if (el) {
388
+ el.style.left = `${newX}px`;
389
+ el.style.top = `${newY}px`;
390
+ }
391
+ updateWindowState({ x: newX, y: newY });
392
+ event.preventDefault();
393
+ };
394
+ const onTitlePointerUp = (event) => {
395
+ stopDragging(event);
396
+ };
397
+ const onTitlePointerCancel = (event) => {
398
+ stopDragging(event);
376
399
  };
377
400
  const onWindowMounted = () => {
378
401
  windowManager.updateWindow(initialWindowState.id, {
@@ -380,17 +403,18 @@ function Window({
380
403
  ref
381
404
  });
382
405
  windowManager.setActiveWindow(initialWindowState.id);
406
+ defuss.$(document).on("blur", () => stopDragging());
407
+ defuss.$(document).on("visibilitychange", () => {
408
+ if (document.hidden) stopDragging();
409
+ });
383
410
  };
384
411
  const onCloseClick = () => windowManager.closeWindow(initialWindowState.id);
385
- const onMaximizeClick = async () => {
412
+ const onMaximizeClick = () => {
386
413
  const currentState = windowManager.getWindow(initialWindowState.id);
387
- if (currentState?.maximized) {
388
- windowManager.restoreWindow(initialWindowState.id);
389
- } else {
390
- windowManager.maximizeWindow(initialWindowState.id);
391
- }
414
+ if (currentState?.maximized) windowManager.restoreWindow(initialWindowState.id);
415
+ else windowManager.maximizeWindow(initialWindowState.id);
392
416
  };
393
- const onMinimizeClick = async () => {
417
+ const onMinimizeClick = () => {
394
418
  windowManager.minimizeWindow(initialWindowState.id);
395
419
  };
396
420
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -412,36 +436,18 @@ function Window({
412
436
  {
413
437
  class: "title-bar",
414
438
  onMount: onWindowMounted,
415
- onMouseDown,
416
- onMouseUp,
417
- onMouseMove,
439
+ onPointerDown: onTitlePointerDown,
440
+ onPointerMove: onTitlePointerMove,
441
+ onPointerUp: onTitlePointerUp,
442
+ onPointerCancel: onTitlePointerCancel,
443
+ onDblClick: onMaximizeClick,
444
+ style: { touchAction: "none" },
418
445
  children: [
419
446
  /* @__PURE__ */ jsxRuntime.jsx("div", { class: "title-bar-text", children: title }),
420
447
  /* @__PURE__ */ jsxRuntime.jsxs("div", { class: "title-bar-controls", children: [
421
- /* @__PURE__ */ jsxRuntime.jsx(
422
- "button",
423
- {
424
- type: "button",
425
- "aria-label": "Minimize",
426
- onClick: onMinimizeClick
427
- }
428
- ),
429
- /* @__PURE__ */ jsxRuntime.jsx(
430
- "button",
431
- {
432
- type: "button",
433
- "aria-label": "Maximize",
434
- onClick: onMaximizeClick
435
- }
436
- ),
437
- /* @__PURE__ */ jsxRuntime.jsx(
438
- "button",
439
- {
440
- type: "button",
441
- "aria-label": "Close",
442
- onClick: onCloseClick
443
- }
444
- )
448
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "aria-label": "Minimize", onClick: onMinimizeClick }),
449
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "aria-label": "Maximize", onClick: onMaximizeClick }),
450
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "aria-label": "Close", onClick: onCloseClick })
445
451
  ] })
446
452
  ]
447
453
  }
package/dist/index.d.cts CHANGED
@@ -1,15 +1,15 @@
1
1
  import * as defuss from 'defuss';
2
- import { Props, CallChainImpl, Dequery, NodeType, Ref } from 'defuss';
2
+ import { Props, CallChainImpl, Dequery, Ref } from 'defuss';
3
3
 
4
- declare function Desktop({ ref }: Props): any;
4
+ declare function Desktop({ ref }: Props<HTMLDivElement>): JSX.Element;
5
5
 
6
- interface ButtonProps extends Props {
6
+ interface ButtonProps extends Props<HTMLButtonElement> {
7
7
  onClick?: () => void;
8
8
  disabled?: boolean;
9
9
  }
10
- declare function Button({ onClick, disabled, children, ref, }: ButtonProps): any;
10
+ declare function Button({ onClick, disabled, children, ref, }: ButtonProps): JSX.Element;
11
11
 
12
- interface LogonScreenProps extends Props {
12
+ interface LogonScreenProps extends Props<HTMLDivElement> {
13
13
  cDriveBasePath?: string;
14
14
  showGuestUser?: boolean;
15
15
  onTurnOffComputer?: () => void;
@@ -20,7 +20,7 @@ type LoginForm = {
20
20
  username: string;
21
21
  password: string;
22
22
  };
23
- declare const LogonScreen: ({ cDriveBasePath, showGuestUser, onTurnOffComputer, onGuestLogon, onUserLogonSubmit, ref, }: LogonScreenProps) => any;
23
+ declare const LogonScreen: ({ cDriveBasePath, showGuestUser, onTurnOffComputer, onGuestLogon, onUserLogonSubmit, ref, }: LogonScreenProps) => JSX.Element;
24
24
 
25
25
  interface DefussAppConfig {
26
26
  name: string;
@@ -85,16 +85,16 @@ declare class DesktopManager {
85
85
  }
86
86
  declare const desktopManager: DesktopManager;
87
87
 
88
- interface ShellProps extends Props {
88
+ interface ShellProps extends Props<HTMLDivElement> {
89
89
  desktopConfig: CreateDesktopOptions;
90
90
  }
91
- declare function Shell({ ref, desktopConfig, }: ShellProps): any;
91
+ declare function Shell({ ref, desktopConfig, }: ShellProps): JSX.Element;
92
92
 
93
- declare const Taskbar: () => any;
93
+ declare const Taskbar: () => JSX.Element;
94
94
 
95
- declare const StartButton: () => any;
95
+ declare const StartButton: () => JSX.Element;
96
96
 
97
- declare const StartMenu: () => any;
97
+ declare const StartMenu: () => JSX.Element;
98
98
 
99
99
  declare class DequeryWithWindowManager<NT> extends CallChainImpl<NT, DequeryWithWindowManager<NT> & Dequery<NT>> {
100
100
  createDesktopApp(options: DefussAppConfig): PromiseLike<DefussApp>;
@@ -107,7 +107,7 @@ declare class DequeryWithWindowManager<NT> extends CallChainImpl<NT, DequeryWith
107
107
  * @param options - Optional dequery options
108
108
  * @returns Extended dequery instance with createWindow and createTaskbar methods
109
109
  */
110
- declare const $: <NT = defuss.DequerySyncMethodReturnType>(selectorRefOrEl: string | NodeType | defuss.Ref<any, NodeType> | defuss.RenderInput | Function, options?: (defuss.DequeryOptions<NT> & JSX.HTMLAttributesLowerCase & {
110
+ declare const $: <NT = defuss.NodeType>(selectorRefOrEl: string | defuss.NodeType | defuss.Ref<defuss.NodeType, any> | defuss.RenderInput | Function, options?: (defuss.DequeryOptions<NT> & JSX.HTMLAttributesLowerCase<defuss.DOMElement> & JSX.HTMLAttributesLowerCase<defuss.DOMElement> & {
111
111
  html?: string;
112
112
  text?: string;
113
113
  }) | undefined) => DequeryWithWindowManager<unknown>;
@@ -142,7 +142,7 @@ interface CreateWindowOptions {
142
142
  interface WindowState {
143
143
  id: string;
144
144
  el: HTMLElement;
145
- ref: Ref<WindowRefState>;
145
+ ref: Ref<HTMLElement, WindowRefState>;
146
146
  title: string;
147
147
  icon: string;
148
148
  width: number;
package/dist/index.d.mts CHANGED
@@ -1,15 +1,15 @@
1
1
  import * as defuss from 'defuss';
2
- import { Props, CallChainImpl, Dequery, NodeType, Ref } from 'defuss';
2
+ import { Props, CallChainImpl, Dequery, Ref } from 'defuss';
3
3
 
4
- declare function Desktop({ ref }: Props): any;
4
+ declare function Desktop({ ref }: Props<HTMLDivElement>): JSX.Element;
5
5
 
6
- interface ButtonProps extends Props {
6
+ interface ButtonProps extends Props<HTMLButtonElement> {
7
7
  onClick?: () => void;
8
8
  disabled?: boolean;
9
9
  }
10
- declare function Button({ onClick, disabled, children, ref, }: ButtonProps): any;
10
+ declare function Button({ onClick, disabled, children, ref, }: ButtonProps): JSX.Element;
11
11
 
12
- interface LogonScreenProps extends Props {
12
+ interface LogonScreenProps extends Props<HTMLDivElement> {
13
13
  cDriveBasePath?: string;
14
14
  showGuestUser?: boolean;
15
15
  onTurnOffComputer?: () => void;
@@ -20,7 +20,7 @@ type LoginForm = {
20
20
  username: string;
21
21
  password: string;
22
22
  };
23
- declare const LogonScreen: ({ cDriveBasePath, showGuestUser, onTurnOffComputer, onGuestLogon, onUserLogonSubmit, ref, }: LogonScreenProps) => any;
23
+ declare const LogonScreen: ({ cDriveBasePath, showGuestUser, onTurnOffComputer, onGuestLogon, onUserLogonSubmit, ref, }: LogonScreenProps) => JSX.Element;
24
24
 
25
25
  interface DefussAppConfig {
26
26
  name: string;
@@ -85,16 +85,16 @@ declare class DesktopManager {
85
85
  }
86
86
  declare const desktopManager: DesktopManager;
87
87
 
88
- interface ShellProps extends Props {
88
+ interface ShellProps extends Props<HTMLDivElement> {
89
89
  desktopConfig: CreateDesktopOptions;
90
90
  }
91
- declare function Shell({ ref, desktopConfig, }: ShellProps): any;
91
+ declare function Shell({ ref, desktopConfig, }: ShellProps): JSX.Element;
92
92
 
93
- declare const Taskbar: () => any;
93
+ declare const Taskbar: () => JSX.Element;
94
94
 
95
- declare const StartButton: () => any;
95
+ declare const StartButton: () => JSX.Element;
96
96
 
97
- declare const StartMenu: () => any;
97
+ declare const StartMenu: () => JSX.Element;
98
98
 
99
99
  declare class DequeryWithWindowManager<NT> extends CallChainImpl<NT, DequeryWithWindowManager<NT> & Dequery<NT>> {
100
100
  createDesktopApp(options: DefussAppConfig): PromiseLike<DefussApp>;
@@ -107,7 +107,7 @@ declare class DequeryWithWindowManager<NT> extends CallChainImpl<NT, DequeryWith
107
107
  * @param options - Optional dequery options
108
108
  * @returns Extended dequery instance with createWindow and createTaskbar methods
109
109
  */
110
- declare const $: <NT = defuss.DequerySyncMethodReturnType>(selectorRefOrEl: string | NodeType | defuss.Ref<any, NodeType> | defuss.RenderInput | Function, options?: (defuss.DequeryOptions<NT> & JSX.HTMLAttributesLowerCase & {
110
+ declare const $: <NT = defuss.NodeType>(selectorRefOrEl: string | defuss.NodeType | defuss.Ref<defuss.NodeType, any> | defuss.RenderInput | Function, options?: (defuss.DequeryOptions<NT> & JSX.HTMLAttributesLowerCase<defuss.DOMElement> & JSX.HTMLAttributesLowerCase<defuss.DOMElement> & {
111
111
  html?: string;
112
112
  text?: string;
113
113
  }) | undefined) => DequeryWithWindowManager<unknown>;
@@ -142,7 +142,7 @@ interface CreateWindowOptions {
142
142
  interface WindowState {
143
143
  id: string;
144
144
  el: HTMLElement;
145
- ref: Ref<WindowRefState>;
145
+ ref: Ref<HTMLElement, WindowRefState>;
146
146
  title: string;
147
147
  icon: string;
148
148
  width: number;
package/dist/index.mjs CHANGED
@@ -44,7 +44,9 @@ class WindowManager {
44
44
  windows = [];
45
45
  constructor() {
46
46
  $$1(() => {
47
- desktopManager.onResize(debounce(this.onDesktopResized.bind(this), 50));
47
+ if (desktopManager?.onResize) {
48
+ desktopManager.onResize(debounce(this.onDesktopResized.bind(this), 50));
49
+ }
48
50
  });
49
51
  }
50
52
  onDesktopResized(dimensions) {
@@ -288,6 +290,11 @@ function Window({
288
290
  }
289
291
  }) {
290
292
  let isDragging = false;
293
+ let dragPointerId = null;
294
+ let dragStartMouse = { x: 0, y: 0 };
295
+ let dragStartWin = { x: 0, y: 0 };
296
+ let lastWin = { x, y };
297
+ let capturedTitleBar = null;
291
298
  const initialWindowState = windowManager.addWindow({
292
299
  id,
293
300
  title,
@@ -299,7 +306,7 @@ function Window({
299
306
  minimizable,
300
307
  maximizable
301
308
  });
302
- let dragStart = { x: initialWindowState.x, y: initialWindowState.y };
309
+ lastWin = { x: initialWindowState.x, y: initialWindowState.y };
303
310
  ref.state = {
304
311
  onClose: () => {
305
312
  console.log("Window closed");
@@ -313,15 +320,9 @@ function Window({
313
320
  console.log("Window maximized");
314
321
  onMaximize();
315
322
  },
316
- minimize: () => {
317
- windowManager.minimizeWindow(initialWindowState.id);
318
- },
319
- maximize: () => {
320
- windowManager.maximizeWindow(initialWindowState.id);
321
- },
322
- restore: () => {
323
- windowManager.restoreWindow(initialWindowState.id);
324
- },
323
+ minimize: () => windowManager.minimizeWindow(initialWindowState.id),
324
+ maximize: () => windowManager.maximizeWindow(initialWindowState.id),
325
+ restore: () => windowManager.restoreWindow(initialWindowState.id),
325
326
  close: () => {
326
327
  console.log("Closing window");
327
328
  windowManager.closeWindow(initialWindowState.id);
@@ -332,45 +333,67 @@ function Window({
332
333
  windowManager.updateWindow(initialWindowState.id, newState);
333
334
  },
334
335
  250
335
- // 1/4 second throttle
336
336
  );
337
- const onMouseMove = async (event) => {
337
+ const onWindowMouseDown = (_event) => windowManager.setActiveWindow(initialWindowState.id);
338
+ const getCurrentWinPos = () => {
339
+ const el = ref.current;
340
+ if (!el) return { x: lastWin.x, y: lastWin.y };
341
+ const left = Number.parseFloat(el.style.left);
342
+ const top = Number.parseFloat(el.style.top);
343
+ return {
344
+ x: Number.isFinite(left) ? left : el.offsetLeft,
345
+ y: Number.isFinite(top) ? top : el.offsetTop
346
+ };
347
+ };
348
+ const stopDragging = (event) => {
338
349
  if (!isDragging) return;
339
- const mouseEvent = event;
340
- const win = await $$1(ref);
341
- const deltaX = mouseEvent.clientX - dragStart.x;
342
- const deltaY = mouseEvent.clientY - dragStart.y;
343
- const currentOffset = await win.offset();
344
- if (currentOffset) {
345
- const newX = currentOffset.left + deltaX;
346
- const newY = currentOffset.top + deltaY;
347
- updateWindowState({ x: newX, y: newY });
348
- await win.css({
349
- left: `${newX}px`,
350
- top: `${newY}px`
351
- });
350
+ if (event && capturedTitleBar && typeof capturedTitleBar.releasePointerCapture === "function" && dragPointerId === event.pointerId) {
351
+ try {
352
+ capturedTitleBar.releasePointerCapture(event.pointerId);
353
+ } catch {
354
+ }
352
355
  }
353
- dragStart = { x: mouseEvent.clientX, y: mouseEvent.clientY };
356
+ isDragging = false;
357
+ dragPointerId = null;
358
+ capturedTitleBar = null;
359
+ windowManager.updateWindow(initialWindowState.id, { x: lastWin.x, y: lastWin.y });
354
360
  };
355
- const onWindowMouseDown = (event) => windowManager.setActiveWindow(initialWindowState.id);
356
- const onMouseDown = (event) => {
357
- if (event.target.tagName === "BUTTON") {
358
- isDragging = false;
359
- return;
360
- }
361
+ const onTitlePointerDown = (event) => {
362
+ if (event.pointerType === "mouse" && event.button !== 0) return;
363
+ const target = event.target;
364
+ if (target?.tagName === "BUTTON") return;
365
+ const titleBarEl = target?.closest?.(".title-bar");
366
+ if (!titleBarEl) return;
367
+ windowManager.setActiveWindow(initialWindowState.id);
361
368
  isDragging = true;
362
- dragStart = {
363
- x: event.clientX,
364
- y: event.clientY
365
- };
366
- $$1(document).on("mousemove", onMouseMove);
367
- $$1(document).on("mouseup", onMouseUp);
369
+ dragPointerId = event.pointerId;
370
+ capturedTitleBar = titleBarEl;
371
+ dragStartMouse = { x: event.clientX, y: event.clientY };
372
+ dragStartWin = getCurrentWinPos();
373
+ if (typeof titleBarEl.setPointerCapture === "function") {
374
+ titleBarEl.setPointerCapture(event.pointerId);
375
+ }
368
376
  event.preventDefault();
369
377
  };
370
- const onMouseUp = () => {
371
- isDragging = false;
372
- $$1(document).off("mousemove", onMouseMove);
373
- $$1(document).off("mouseup", onMouseUp);
378
+ const onTitlePointerMove = (event) => {
379
+ if (!isDragging) return;
380
+ if (dragPointerId !== null && event.pointerId !== dragPointerId) return;
381
+ const newX = dragStartWin.x + (event.clientX - dragStartMouse.x);
382
+ const newY = dragStartWin.y + (event.clientY - dragStartMouse.y);
383
+ lastWin = { x: newX, y: newY };
384
+ const el = ref.current;
385
+ if (el) {
386
+ el.style.left = `${newX}px`;
387
+ el.style.top = `${newY}px`;
388
+ }
389
+ updateWindowState({ x: newX, y: newY });
390
+ event.preventDefault();
391
+ };
392
+ const onTitlePointerUp = (event) => {
393
+ stopDragging(event);
394
+ };
395
+ const onTitlePointerCancel = (event) => {
396
+ stopDragging(event);
374
397
  };
375
398
  const onWindowMounted = () => {
376
399
  windowManager.updateWindow(initialWindowState.id, {
@@ -378,17 +401,18 @@ function Window({
378
401
  ref
379
402
  });
380
403
  windowManager.setActiveWindow(initialWindowState.id);
404
+ $$1(document).on("blur", () => stopDragging());
405
+ $$1(document).on("visibilitychange", () => {
406
+ if (document.hidden) stopDragging();
407
+ });
381
408
  };
382
409
  const onCloseClick = () => windowManager.closeWindow(initialWindowState.id);
383
- const onMaximizeClick = async () => {
410
+ const onMaximizeClick = () => {
384
411
  const currentState = windowManager.getWindow(initialWindowState.id);
385
- if (currentState?.maximized) {
386
- windowManager.restoreWindow(initialWindowState.id);
387
- } else {
388
- windowManager.maximizeWindow(initialWindowState.id);
389
- }
412
+ if (currentState?.maximized) windowManager.restoreWindow(initialWindowState.id);
413
+ else windowManager.maximizeWindow(initialWindowState.id);
390
414
  };
391
- const onMinimizeClick = async () => {
415
+ const onMinimizeClick = () => {
392
416
  windowManager.minimizeWindow(initialWindowState.id);
393
417
  };
394
418
  return /* @__PURE__ */ jsxs(
@@ -410,36 +434,18 @@ function Window({
410
434
  {
411
435
  class: "title-bar",
412
436
  onMount: onWindowMounted,
413
- onMouseDown,
414
- onMouseUp,
415
- onMouseMove,
437
+ onPointerDown: onTitlePointerDown,
438
+ onPointerMove: onTitlePointerMove,
439
+ onPointerUp: onTitlePointerUp,
440
+ onPointerCancel: onTitlePointerCancel,
441
+ onDblClick: onMaximizeClick,
442
+ style: { touchAction: "none" },
416
443
  children: [
417
444
  /* @__PURE__ */ jsx("div", { class: "title-bar-text", children: title }),
418
445
  /* @__PURE__ */ jsxs("div", { class: "title-bar-controls", children: [
419
- /* @__PURE__ */ jsx(
420
- "button",
421
- {
422
- type: "button",
423
- "aria-label": "Minimize",
424
- onClick: onMinimizeClick
425
- }
426
- ),
427
- /* @__PURE__ */ jsx(
428
- "button",
429
- {
430
- type: "button",
431
- "aria-label": "Maximize",
432
- onClick: onMaximizeClick
433
- }
434
- ),
435
- /* @__PURE__ */ jsx(
436
- "button",
437
- {
438
- type: "button",
439
- "aria-label": "Close",
440
- onClick: onCloseClick
441
- }
442
- )
446
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Minimize", onClick: onMinimizeClick }),
447
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Maximize", onClick: onMaximizeClick }),
448
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Close", onClick: onCloseClick })
443
449
  ] })
444
450
  ]
445
451
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "defuss-desktop",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -53,9 +53,9 @@
53
53
  "node": "^18.17.1 || ^20.3.0 || >=21.0.0"
54
54
  },
55
55
  "dependencies": {
56
- "defuss": "^2.1.10",
57
- "defuss-runtime": "^1.2.1",
58
- "defuss-transval": "^1.3.0"
56
+ "defuss": "workspace:*",
57
+ "defuss-runtime": "workspace:*",
58
+ "defuss-transval": "workspace:*"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@vitest/coverage-v8": "^4.0.17",
@@ -65,4 +65,4 @@
65
65
  "typescript": "^5.9.3",
66
66
  "vitest": "^4.0.17"
67
67
  }
68
- }
68
+ }