From 40ce12f47f81036b0ee023d6db9ca0379b462a95 Mon Sep 17 00:00:00 2001 From: Stefans Mezulis Date: Thu, 23 Dec 2021 12:12:47 +0000 Subject: [PATCH] Handle unordered add / position change events Fixes (some cases of) plugins ignoring saved `(x, y)` coordinates when a project is loaded. The canvas can get notified of a plugin's position before the plugin is actually added, so when the plugin is actually it just goes to the default position. This happens because `PatchbayClientPositionChanged` events can arrive before `PatchbayClientAdded` events, as seen in debug logs like this: ``` ... PatchCanvas::joinGroup(30) PatchCanvas::joinGroup(30) - unable to find groups to join PatchCanvas::setGroupPos(30, 1118, 591, 0, 0) PatchCanvas::setGroupPos(30, 1118, 591, 0, 0) - unable to find group to reposition PatchCanvas::addGroup(30, b'Audio to CV', SPLIT_UNDEF, ICON_PLUGIN) ... ``` If this happens, the canvas box will be placed in the default position, rather than obeying the `PatchbayClientPositionChanged` signal. This PR keeps track of missed events and then applies them once the object is actually added. --- source/frontend/patchcanvas/__init__.py | 3 +++ source/frontend/patchcanvas/patchcanvas.py | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/source/frontend/patchcanvas/__init__.py b/source/frontend/patchcanvas/__init__.py index cada20c53..cc18e5f83 100644 --- a/source/frontend/patchcanvas/__init__.py +++ b/source/frontend/patchcanvas/__init__.py @@ -145,6 +145,9 @@ class Canvas(object): self.initial_pos = QPointF(0, 0) self.size_rect = QRectF() + self.pending_group_joins = set() + self.pending_position_changes = {} + def callback(self, action, value1, value2, value_str): print("Canvas::callback({}, {}, {}, {})".format(action, value1, value2, value_str)) diff --git a/source/frontend/patchcanvas/patchcanvas.py b/source/frontend/patchcanvas/patchcanvas.py index b888512b4..26b1079ed 100644 --- a/source/frontend/patchcanvas/patchcanvas.py +++ b/source/frontend/patchcanvas/patchcanvas.py @@ -400,6 +400,17 @@ def addGroup(group_id, group_name, split=SPLIT_UNDEF, icon=ICON_APPLICATION): canvas.group_list.append(group_dict) + # Callbacks can arrive out of order, so we might have pending events. + if group_id in canvas.pending_group_joins: + joinGroup(group_id) + canvas.pending_group_joins.remove(group_id) + + if group_id in canvas.pending_position_changes: + position_change = canvas.pending_position_changes[group_id] + setGroupPosFull(*position_change) + del canvas.pending_position_changes[group_id] + + if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups: CanvasItemFX(group_box, True, False) else: @@ -602,6 +613,7 @@ def joinGroup(group_id): # FIXME if not (item and s_item): qCritical("PatchCanvas::joinGroup(%i) - unable to find groups to join" % group_id) + canvas.pending_group_joins.add(group_id) return port_list_ids = list(item.getPortList()) @@ -755,6 +767,7 @@ def setGroupPosFull(group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group qCritical("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i) - unable to find group to reposition" % ( group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i)) + canvas.pending_position_changes[group_id] = (group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i) # ------------------------------------------------------------------------------------------------------------