Skip to content

Commit e29a240

Browse files
committed
widgets: get k3d to not crash when putting tab in background using visibility context
1 parent 1886509 commit e29a240

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/packages/frontend/jupyter/output-messages/ipywidget.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { Icon } from "@cocalc/frontend/components/icon";
77
import { Alert, Button } from "antd";
88
import type { JupyterActions } from "../browser-actions";
99
import { Map } from "immutable";
10+
import { useFrameContext } from "@cocalc/frontend/frame-editors/frame-tree/frame-context";
11+
12+
// TODO: it would be better if somehow this were in @cocalc/jupyter, to 100% ensure css stays aligned.
1013
require("@jupyter-widgets/controls/css/widgets.css");
1114

1215
let loadFontAwesomeDone = false;
@@ -34,9 +37,13 @@ export function IpyWidget({ id: cell_id, value, actions }: WidgetProps) {
3437
// console.log("IpyWidget", { value: value.toJS(), actions });
3538
const [unknown, setUnknown] = useState<boolean>(false);
3639
const divRef = useRef<any>(null);
40+
// We *ONLY* render widgets when they are visible. Why?
41+
// (1) some widgets -- k3d labels!! -- assume they are visible, and just totally crash if not, due to bad code
42+
// (2) efficiency.
43+
const { isVisible } = useFrameContext();
3744

3845
useEffect(() => {
39-
if (actions == null) {
46+
if (actions == null || !isVisible) {
4047
// console.log("IpyWidget: not rendering due to actions=null");
4148
return;
4249
}
@@ -64,7 +71,11 @@ export function IpyWidget({ id: cell_id, value, actions }: WidgetProps) {
6471
return;
6572
}
6673
render({ manager, id, div });
67-
}, []);
74+
75+
return () => {
76+
$(div).empty();
77+
};
78+
}, [isVisible]);
6879

6980
if (unknown) {
7081
const msg = "Run cell to load widget.";

src/packages/frontend/jupyter/widgets/manager.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import React from "react";
2424
import ReactDOM from "react-dom/client";
2525
import type { JupyterActions } from "@cocalc/frontend/jupyter/browser-actions";
2626
import { FileContext } from "@cocalc/frontend/lib/file-context";
27+
import { FrameContext } from "@cocalc/frontend/frame-editors/frame-tree/frame-context";
28+
2729
import { delay } from "awaiting";
2830

2931
const K3D_DELAY_MS = 25;
@@ -718,14 +720,23 @@ class Environment implements WidgetEnvironment {
718720
// widgets will refresh if you scroll them off the screen and back.
719721
const trust = actions.store.get("trust");
720722
const component = React.createElement(
721-
FileContext.Provider,
723+
FrameContext.Provider,
722724
{
723-
value: { noSanitize: trust, project_id },
725+
// @ts-ignore -- we aren't filling in all the standard stuff
726+
// also we just always put isVisible true, since the output widget itself
727+
// (which has proper context) gets not rendered and that contains this.
728+
value: { isVisible: true },
724729
},
725730
React.createElement(
726-
CellOutputMessage,
727-
{ message, actions, project_id, trust },
728-
null,
731+
FileContext.Provider,
732+
{
733+
value: { noSanitize: trust, project_id },
734+
},
735+
React.createElement(
736+
CellOutputMessage,
737+
{ message, actions, project_id, trust },
738+
null,
739+
),
729740
),
730741
);
731742
const root = ReactDOM.createRoot(myDiv);

0 commit comments

Comments
 (0)