@gtkx/react 0.10.0 → 0.10.1

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.
@@ -1,6 +1,7 @@
1
1
  import { beginBatch, endBatch, getObjectId } from "@gtkx/ffi";
2
2
  import React from "react";
3
3
  import { createNode } from "./factory.js";
4
+ import { clearFiredSignals } from "./nodes/internal/signal-store.js";
4
5
  import { flushAfterCommit } from "./scheduler.js";
5
6
  if (!globalThis.__GTKX_CONTAINER_NODE_CACHE__) {
6
7
  globalThis.__GTKX_CONTAINER_NODE_CACHE__ = new Map();
@@ -78,6 +79,7 @@ export function createHostConfig() {
78
79
  },
79
80
  resetAfterCommit: () => {
80
81
  endBatch();
82
+ clearFiredSignals();
81
83
  flushAfterCommit();
82
84
  committing = false;
83
85
  },
package/dist/jsx.d.ts CHANGED
@@ -710,10 +710,5 @@ declare global {
710
710
  export * from "./generated/jsx.js";
711
711
  declare module "./generated/jsx.js" {
712
712
  interface WidgetProps extends EventControllerProps {
713
- /**
714
- * Called when any property on this widget changes.
715
- * @param propName - The name of the property that changed
716
- */
717
- onNotify?: (propName: string) => void;
718
713
  }
719
714
  }
@@ -47,7 +47,10 @@ export class ActionRowChild extends VirtualNode {
47
47
  }
48
48
  scheduleAfterCommit(() => {
49
49
  if (parent) {
50
- parent.remove(widget);
50
+ const currentParent = widget.getParent();
51
+ if (currentParent?.equals(parent)) {
52
+ parent.remove(widget);
53
+ }
51
54
  }
52
55
  });
53
56
  }
@@ -57,7 +60,10 @@ export class ActionRowChild extends VirtualNode {
57
60
  if (parent && childrenToRemove.length > 0) {
58
61
  scheduleAfterCommit(() => {
59
62
  for (const widget of childrenToRemove) {
60
- parent.remove(widget);
63
+ const currentParent = widget.getParent();
64
+ if (currentParent?.equals(parent)) {
65
+ parent.remove(widget);
66
+ }
61
67
  }
62
68
  });
63
69
  }
@@ -1,3 +1,4 @@
1
+ import { batch } from "@gtkx/ffi";
1
2
  import { registerNodeClass } from "../registry.js";
2
3
  import { SlotNode } from "./slot.js";
3
4
  class FixedChildNode extends SlotNode {
@@ -25,17 +26,22 @@ class FixedChildNode extends SlotNode {
25
26
  const y = this.props.y ?? 0;
26
27
  if (this.child) {
27
28
  const child = this.child;
28
- const currentParent = child.getParent();
29
- if (currentParent?.equals(fixed)) {
30
- fixed.remove(child);
31
- }
32
- fixed.put(child, x, y);
29
+ batch(() => {
30
+ const currentParent = child.getParent();
31
+ if (currentParent?.equals(fixed)) {
32
+ fixed.remove(child);
33
+ }
34
+ fixed.put(child, x, y);
35
+ });
33
36
  }
34
37
  }
35
38
  onChildChange(oldChild) {
36
39
  const fixed = this.getFixed();
37
40
  if (oldChild) {
38
- fixed.remove(oldChild);
41
+ const parent = oldChild.getParent();
42
+ if (parent?.equals(fixed)) {
43
+ fixed.remove(oldChild);
44
+ }
39
45
  }
40
46
  if (this.child) {
41
47
  this.positionChild();
@@ -1,3 +1,4 @@
1
+ import { batch } from "@gtkx/ffi";
1
2
  import { registerNodeClass } from "../registry.js";
2
3
  import { SlotNode } from "./slot.js";
3
4
  class GridChildNode extends SlotNode {
@@ -29,22 +30,27 @@ class GridChildNode extends SlotNode {
29
30
  const row = this.props.row ?? 0;
30
31
  const columnSpan = this.props.columnSpan ?? 1;
31
32
  const rowSpan = this.props.rowSpan ?? 1;
32
- const existingChild = grid.getChildAt(column, row);
33
- if (existingChild && !existingChild.equals(this.child)) {
34
- grid.remove(existingChild);
35
- }
36
- if (this.child) {
37
- const currentParent = this.child.getParent();
38
- if (currentParent?.equals(grid)) {
39
- grid.remove(this.child);
33
+ batch(() => {
34
+ const existingChild = grid.getChildAt(column, row);
35
+ if (existingChild && !existingChild.equals(this.child)) {
36
+ grid.remove(existingChild);
40
37
  }
41
- grid.attach(this.child, column, row, columnSpan, rowSpan);
42
- }
38
+ if (this.child) {
39
+ const currentParent = this.child.getParent();
40
+ if (currentParent?.equals(grid)) {
41
+ grid.remove(this.child);
42
+ }
43
+ grid.attach(this.child, column, row, columnSpan, rowSpan);
44
+ }
45
+ });
43
46
  }
44
47
  onChildChange(oldChild) {
45
48
  const grid = this.getGrid();
46
49
  if (oldChild) {
47
- grid.remove(oldChild);
50
+ const parent = oldChild.getParent();
51
+ if (parent?.equals(grid)) {
52
+ grid.remove(oldChild);
53
+ }
48
54
  }
49
55
  if (this.child) {
50
56
  this.attachChild();
@@ -1,5 +1,6 @@
1
1
  import * as GObject from "@gtkx/ffi/gobject";
2
2
  export type SignalHandler = (...args: any[]) => any;
3
+ export declare const clearFiredSignals: () => void;
3
4
  export declare class SignalStore {
4
5
  private signalHandlers;
5
6
  private disconnect;
@@ -16,6 +16,10 @@ const LIFECYCLE_SIGNALS = new Set([
16
16
  "unbind",
17
17
  "teardown",
18
18
  ]);
19
+ const firedThisCommit = new Set();
20
+ export const clearFiredSignals = () => {
21
+ firedThisCommit.clear();
22
+ };
19
23
  export class SignalStore {
20
24
  signalHandlers = new Map();
21
25
  disconnect(obj, signal) {
@@ -31,8 +35,14 @@ export class SignalStore {
31
35
  const objectId = getObjectId(obj.id);
32
36
  const key = `${objectId}:${signal}`;
33
37
  const wrappedHandler = (...args) => {
34
- if (isCommitting() && !LIFECYCLE_SIGNALS.has(signal)) {
35
- return;
38
+ if (LIFECYCLE_SIGNALS.has(signal)) {
39
+ return handler(...args);
40
+ }
41
+ if (isCommitting()) {
42
+ if (firedThisCommit.has(key)) {
43
+ return;
44
+ }
45
+ firedThisCommit.add(key);
36
46
  }
37
47
  return handler(...args);
38
48
  };
@@ -14,7 +14,10 @@ class OverlayChildNode extends SlotNode {
14
14
  onChildChange(oldChild) {
15
15
  const overlay = this.getOverlay();
16
16
  if (oldChild) {
17
- overlay.removeOverlay(oldChild);
17
+ const parent = oldChild.getParent();
18
+ if (parent?.equals(overlay)) {
19
+ overlay.removeOverlay(oldChild);
20
+ }
18
21
  }
19
22
  if (this.child) {
20
23
  overlay.addOverlay(this.child);
@@ -21,7 +21,10 @@ export class PackChild extends VirtualNode {
21
21
  if (parent && childrenToRemove.length > 0) {
22
22
  scheduleAfterCommit(() => {
23
23
  for (const widget of childrenToRemove) {
24
- parent.remove(widget);
24
+ const currentParent = widget.getParent();
25
+ if (currentParent?.equals(parent)) {
26
+ parent.remove(widget);
27
+ }
25
28
  }
26
29
  });
27
30
  }
@@ -54,13 +57,17 @@ export class PackChild extends VirtualNode {
54
57
  throw new Error(`Cannot remove '${child.typeName}' from '${this.typeName}': expected Widget`);
55
58
  }
56
59
  const widget = child.container;
60
+ const parent = this.parent;
57
61
  const index = this.children.indexOf(widget);
58
62
  if (index !== -1) {
59
63
  this.children.splice(index, 1);
60
64
  }
61
65
  scheduleAfterCommit(() => {
62
- if (this.parent) {
63
- this.parent.remove(widget);
66
+ if (parent) {
67
+ const currentParent = widget.getParent();
68
+ if (currentParent?.equals(parent)) {
69
+ parent.remove(widget);
70
+ }
64
71
  }
65
72
  });
66
73
  }
@@ -68,7 +68,10 @@ class StackPageNode extends SlotNode {
68
68
  if (!oldChild) {
69
69
  return;
70
70
  }
71
- parent.remove(oldChild);
71
+ const currentParent = oldChild.getParent();
72
+ if (currentParent?.equals(parent)) {
73
+ parent.remove(oldChild);
74
+ }
72
75
  }
73
76
  onChildChange(oldChild) {
74
77
  this.removePage(oldChild);
@@ -17,7 +17,10 @@ export class ToolbarChildNode extends SlotNode {
17
17
  onChildChange(oldChild) {
18
18
  const toolbar = this.getToolbar();
19
19
  if (oldChild) {
20
- toolbar.remove(oldChild);
20
+ const parent = oldChild.getParent();
21
+ if (parent?.equals(toolbar)) {
22
+ toolbar.remove(oldChild);
23
+ }
21
24
  }
22
25
  if (this.child) {
23
26
  const position = this.getPosition();
@@ -217,8 +217,8 @@ export class WidgetNode extends Node {
217
217
  }
218
218
  case "onNotify": {
219
219
  const wrappedHandler = handler
220
- ? (_obj, pspec) => {
221
- handler(pspec.getName());
220
+ ? (obj, pspec) => {
221
+ handler(obj, pspec.getName());
222
222
  }
223
223
  : undefined;
224
224
  this.signalStore.set(this.container, "notify", wrappedHandler);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/react",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Build GTK4 desktop applications with React and TypeScript",
5
5
  "keywords": [
6
6
  "gtk",
@@ -36,8 +36,8 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "react-reconciler": "^0.33.0",
39
- "@gtkx/ffi": "0.10.0",
40
- "@gtkx/gir": "0.10.0"
39
+ "@gtkx/ffi": "0.10.1",
40
+ "@gtkx/gir": "0.10.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react-reconciler": "^0.32.3",