Skip to content

Commit 76439e8

Browse files
committed
Properly handle canvas visibility like Pd to prevent crashes
1 parent 0ac26f0 commit 76439e8

8 files changed

Lines changed: 31 additions & 64 deletions

File tree

Libraries/pure-data

Source/Canvas.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,6 @@ void Canvas::zoomToFitAll()
991991

992992
void Canvas::tabChanged()
993993
{
994-
patch.setCurrent();
995-
996994
synchronise();
997995
updateDrawables();
998996

@@ -1732,10 +1730,7 @@ void Canvas::dragAndDropPaste(String const& patchString, Point<int> const mouseP
17321730
// Load state from pd
17331731
performSynchronise();
17341732

1735-
patch.setCurrent();
1736-
17371733
SmallArray<t_gobj*> pastedObjects;
1738-
17391734
if (auto patchPtr = patch.getPointer()) {
17401735
for (auto* object : objects) {
17411736
auto* objectPtr = object->getPointer();
@@ -1774,8 +1769,6 @@ void Canvas::pasteSelection()
17741769
// Load state from pd
17751770
performSynchronise();
17761771

1777-
patch.setCurrent();
1778-
17791772
SmallArray<t_gobj*> pastedObjects;
17801773

17811774
if (auto patchPtr = patch.getPointer()) {

Source/Objects/GraphOnParent.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,6 @@ class GraphOnParent final : public ObjectBase {
371371
{
372372
if (!canvas) {
373373
canvas = std::make_unique<Canvas>(cnv->editor, subpatch, this);
374-
375-
// Make sure that the graph doesn't become the current canvas
376-
cnv->patch.setCurrent();
377374
cnv->editor->updateCommandStatus();
378375
}
379376

Source/Pd/Instance.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ void Instance::initialisePd(String& pdlua_version)
340340
return;
341341

342342
t_canvas* glist = reinterpret_cast<struct _glist*>(argv->a_w.w_gpointer);
343+
if(!glist->gl_owner) break;
343344

344345
if (atom_getfloat(argv + 1)) {
345346
File patchFile;

Source/Pd/Interface.h

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ extern void clear_class_loadsym();
2828

2929
namespace pd {
3030

31+
// Sometimes, we need to lie to Pd and say a patch has a window to get accurate information
32+
// This scoped helper sets a canvas as current temporarily
33+
struct ScopedCurrentCanvas
34+
{
35+
t_canvas* glist;
36+
int hadWindow = 0;
37+
ScopedCurrentCanvas(t_glist* x) : glist(x)
38+
{
39+
hadWindow = glist->gl_havewindow;
40+
glist->gl_havewindow = 1;
41+
}
42+
43+
~ScopedCurrentCanvas()
44+
{
45+
glist->gl_havewindow = hadWindow;
46+
}
47+
};
48+
3149
struct Interface {
3250

3351
static t_canvas* createCanvas(char const* name, char const* path)
@@ -87,6 +105,8 @@ struct Interface {
87105

88106
static void getObjectBounds(t_canvas* cnv, t_gobj* ptr, int* x, int* y, int* w, int* h)
89107
{
108+
ScopedCurrentCanvas scopedCurrent(cnv);
109+
90110
*x = 0;
91111
*y = 0;
92112
*w = 0;
@@ -125,6 +145,8 @@ struct Interface {
125145
/* displace the selection by (dx, dy) pixels */
126146
static void moveObjects(t_canvas* cnv, int const dx, int const dy, SmallArray<t_gobj*> const& objects)
127147
{
148+
ScopedCurrentCanvas scopedCurrent(cnv);
149+
128150
glist_noselect(cnv);
129151

130152
for (auto* obj : objects) {
@@ -633,28 +655,6 @@ struct Interface {
633655
return count;
634656
}
635657

636-
static int canUndo(t_canvas* cnv)
637-
{
638-
t_undo* udo = canvas_undo_get(cnv);
639-
640-
if (udo && udo->u_last) {
641-
return strcmp(udo->u_last->name, "no") != 0;
642-
}
643-
644-
return 0;
645-
}
646-
647-
static int canRedo(t_canvas* cnv)
648-
{
649-
t_undo* udo = canvas_undo_get(cnv);
650-
651-
if (udo && udo->u_last && udo->u_last->next) {
652-
return strcmp(udo->u_last->next->name, "no") != 0;
653-
}
654-
655-
return 0;
656-
}
657-
658658
// Can probably be used as a general purpose undo action on an object?
659659
static void undoApply(t_canvas* cnv, t_gobj* obj)
660660
{
@@ -664,6 +664,8 @@ struct Interface {
664664

665665
static void moveObject(t_canvas* cnv, t_gobj* obj, int const x, int const y)
666666
{
667+
ScopedCurrentCanvas scopedCurrent(cnv);
668+
667669
auto* instanceEditor = getInstanceEditor();
668670
if (!instanceEditor->canvas_undo_already_set_move) {
669671
// canvas_undo_add(cnv, UNDO_MOTION, "motion", canvas_undo_set_move(cnv, 0));

Source/Pd/Patch.cpp

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Patch::~Patch()
5555
Rectangle<int> Patch::getGraphBounds() const
5656
{
5757
if (auto cnv = ptr.get<t_canvas>()) {
58+
ScopedCurrentCanvas scopedCurrent(cnv.get());
5859
if (cnv->gl_isgraph) {
5960
cnv->gl_pixwidth = std::max(10, cnv->gl_pixwidth);
6061
cnv->gl_pixheight = std::max(10, cnv->gl_pixheight);
@@ -180,19 +181,13 @@ void Patch::savePatch()
180181
});
181182
}
182183

183-
void Patch::setCurrent()
184-
{
185-
if (auto patch = ptr.get<t_glist>()) {
186-
// Ugly fix: plugdata needs gl_havewindow to always be true!
187-
patch->gl_havewindow = true;
188-
canvas_create_editor(patch.get());
189-
}
190-
}
191-
192184
void Patch::setVisible(bool const shouldVis)
193185
{
194186
if (auto patch = ptr.get<t_glist>()) {
195-
patch->gl_mapped = shouldVis;
187+
t_atom vis;
188+
SETFLOAT(&vis, static_cast<float>(shouldVis));
189+
pd_typedmess(patch.cast<t_pd>(), instance->generateSymbol("vis"), 1, &vis);
190+
pd_typedmess(patch.cast<t_pd>(), instance->generateSymbol("map"), 1, &vis);
196191
}
197192
}
198193

@@ -216,8 +211,6 @@ Connections Patch::getConnections() const
216211

217212
HeapArray<pd::WeakReference> Patch::getObjects()
218213
{
219-
setCurrent();
220-
221214
HeapArray<pd::WeakReference> objects;
222215
if (auto patch = ptr.get<t_glist>()) {
223216
for (t_gobj* y = patch->gl_list; y; y = y->g_next) {
@@ -305,7 +298,6 @@ t_gobj* Patch::createObject(int const x, int const y, String const& name)
305298
}
306299

307300
if (auto patch = ptr.get<t_glist>()) {
308-
setCurrent();
309301
return pd::Interface::createObject(patch.get(), typesymbol, argc, argv.data());
310302
}
311303

@@ -321,8 +313,6 @@ t_gobj* Patch::renameObject(t_object* obj, String const& name)
321313
String const newName = tokens.joinIntoString(" ");
322314

323315
if (auto patch = ptr.get<t_glist>()) {
324-
setCurrent();
325-
326316
pd::Interface::renameObject(patch.get(), &obj->te_g, newName.toRawUTF8(), newName.getNumBytesAsUTF8());
327317
return pd::Interface::getNewest(patch.get());
328318
}
@@ -446,7 +436,6 @@ void Patch::paste(Point<int> const position)
446436
void Patch::duplicate(SmallArray<t_gobj*> const& objects, t_outconnect const* connection)
447437
{
448438
if (auto patch = ptr.get<t_glist>()) {
449-
setCurrent();
450439
pd::Interface::duplicateSelection(patch.get(), objects, connection);
451440
}
452441
}
@@ -480,15 +469,13 @@ bool Patch::canConnect(t_object* src, int const nout, t_object* sink, int const
480469
void Patch::createConnection(t_object* src, int const nout, t_object* sink, int const nin)
481470
{
482471
if (auto patch = ptr.get<t_glist>()) {
483-
setCurrent();
484472
pd::Interface::createConnection(patch.get(), src, nout, sink, nin);
485473
}
486474
}
487475

488476
t_outconnect* Patch::createAndReturnConnection(t_object* src, int const nout, t_object* sink, int const nin)
489477
{
490478
if (auto patch = ptr.get<t_glist>()) {
491-
setCurrent();
492479
return pd::Interface::createConnection(patch.get(), src, nout, sink, nin);
493480
}
494481

@@ -498,15 +485,13 @@ t_outconnect* Patch::createAndReturnConnection(t_object* src, int const nout, t_
498485
void Patch::removeConnection(t_object* src, int const nout, t_object* sink, int const nin, t_symbol* connectionPath)
499486
{
500487
if (auto patch = ptr.get<t_glist>()) {
501-
setCurrent();
502488
pd::Interface::removeConnection(patch.get(), src, nout, sink, nin, connectionPath);
503489
}
504490
}
505491

506492
t_outconnect* Patch::setConnctionPath(t_object* src, int const nout, t_object* sink, int const nin, t_symbol* oldConnectionPath, t_symbol* newConnectionPath)
507493
{
508494
if (auto patch = ptr.get<t_glist>()) {
509-
setCurrent();
510495
return pd::Interface::setConnectionPath(patch.get(), src, nout, sink, nin, oldConnectionPath, newConnectionPath);
511496
}
512497

@@ -516,7 +501,6 @@ t_outconnect* Patch::setConnctionPath(t_object* src, int const nout, t_object* s
516501
void Patch::moveObjects(SmallArray<t_gobj*> const& objects, int const dx, int const dy)
517502
{
518503
if (auto patch = ptr.get<t_glist>()) {
519-
setCurrent();
520504
pd::Interface::moveObjects(patch.get(), dx, dy, objects);
521505
}
522506
}
@@ -533,15 +517,13 @@ void Patch::moveObjectTo(t_gobj* object, int const x, int const y)
533517
void Patch::finishRemove()
534518
{
535519
if (auto patch = ptr.get<t_glist>()) {
536-
setCurrent();
537520
pd::Interface::finishRemove(patch.get());
538521
}
539522
}
540523

541524
void Patch::removeObjects(SmallArray<t_gobj*> const& objects)
542525
{
543526
if (auto patch = ptr.get<t_glist>()) {
544-
setCurrent();
545527
pd::Interface::removeObjects(patch.get(), objects);
546528
}
547529
}
@@ -563,7 +545,6 @@ void Patch::endUndoSequence(String const& name)
563545
void Patch::undo()
564546
{
565547
if (auto patch = ptr.get<t_glist>()) {
566-
setCurrent();
567548
auto const x = patch.get();
568549
glist_noselect(x);
569550

@@ -574,7 +555,6 @@ void Patch::undo()
574555
void Patch::redo()
575556
{
576557
if (auto patch = ptr.get<t_glist>()) {
577-
setCurrent();
578558
auto const x = patch.get();
579559
glist_noselect(x);
580560

@@ -638,7 +618,6 @@ void Patch::setTitle(String const& newTitle)
638618
SETSYMBOL(&args[1], pathSym);
639619

640620
if (auto patch = ptr.get<t_glist>()) {
641-
setCurrent();
642621
pd_typedmess(patch.cast<t_pd>(), instance->generateSymbol("rename"), 2, args.data());
643622
}
644623

Source/Pd/Patch.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ class Patch final : public ReferenceCountedObject {
7171
Move
7272
};
7373

74-
void setCurrent();
75-
7674
bool isDirty() const;
7775
bool canUndo() const;
7876
bool canRedo() const;

Source/PluginProcessor.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ extern "C" {
4444
EXTERN char* pd_version;
4545
}
4646

47-
bool gemWinSetCurrent();
48-
bool gemWinUnsetCurrent();
49-
5047
AudioProcessor::BusesProperties PluginProcessor::buildBusesProperties()
5148
{
5249
#if JUCE_IOS

0 commit comments

Comments
 (0)