Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SG-14250: Disables window closing during loader2 actions to prevent crashing #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,13 @@ def show_dialog(self, title, bundle, widget_class, *args, **kwargs):
# make sure the window raised so it doesn't
# appear behind the main After Effects window
self.logger.debug("Showing dialog: %s" % (title,))

# Adding this window flag will ensure that our dialogs won't be
# tabbed together into a single window on OSX.
if sys.platform == "darwin":
from sgtk.platform.qt import QtCore
dialog.setWindowFlags(dialog.windowFlags() | QtCore.Qt.CustomizeWindowHint)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this fix be in tk-core instead? I think this problem happens in Photoshop as well, right? Maybe in the TankQDialog?


dialog.show()
dialog.raise_()
dialog.activateWindow()
Expand Down
70 changes: 50 additions & 20 deletions hooks/tk-multi-loader2/basic/scene_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@


import sgtk
from sgtk.platform.qt import QtGui, QtCore
from sgtk.platform.qt.tankqdialog import TankQDialog


HookBaseClass = sgtk.get_hook_baseclass()
Expand Down Expand Up @@ -147,26 +149,54 @@ def execute_action(self, name, params, sg_publish_data):
app.log_debug("Execute action called for action %s. "
"Parameters: %s. Publish Data: %s" % (name, params, sg_publish_data))

# resolve path
# toolkit uses utf-8 encoded strings internally and the After Effects API expects unicode
# so convert the path to ensure filenames containing complex characters are supported
path = self.get_publish_path(sg_publish_data).decode('utf-8')

if self.parent.engine.is_adobe_sequence(path):
frame_range = self.parent.engine.find_sequence_range(path)
if frame_range:
glob_path = re.sub("[\[]?([#@]+|%0\d+d)[\]]?", "*{}".format(frame_range[0]), path)
for each_path in sorted(glob.glob(glob_path)):
path = each_path
break

if not os.path.exists(path):
raise IOError("File not found on disk - '%s'" % path)

if name == _ADD_TO_COMP:
self._add_to_comp(path)
if name == _ADD_TO_PROJECT:
self.parent.engine.import_filepath(path)
# If the loader2 dialog is closed during processing it causes some stability problems
# on Windows and OSX. We'll just not allow it to be closed while we're working.
top_level_widgets = [w for w in QtGui.QApplication.topLevelWidgets() if isinstance(w, TankQDialog)]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried here that we're using a class that is part of the internal API of Toolkit. It's unlikely to change, but it's still not part of the official interface of tk-core, which means that accessing it makes it official and we'll have to support this down the road.

From my understanding, during the meeting today you said that this was both an AE and a Photoshop problem. It's also very likely a Unity problem as well. So it's starting to look like a pattern. Maybe this fix should go in the loader app instead. In there we can easily call self.window() and edit the window flags for the current window only. If this sort of issue becomes more common place in other Toolkit apps then we can start thinking of another way to fix this and at least we won't have introduced a dependency on TankQDialog.

What do you think?

top_level_widgets_flags = [(w, w.windowFlags()) for w in top_level_widgets]

try:
# We don't have an easy way from here to get the current loader2 widget, but it's
# not the end of the world if we just disable the close button for all top level
# dialogs that we know came from sgtk while we're in progress.
#
# https://stackoverflow.com/questions/3211272/qt-hide-minimize-maximize-and-close-buttons#
#
for widget in top_level_widgets:
if widget.isVisible():
widget.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowTitleHint | QtCore.Qt.CustomizeWindowHint)
# Changing the window flags hides the dialog, so we re-show it. Doing these in quick succession
# doesn't appear to cause any visual flicker.
widget.show()

# Make sure the window flag change is visible to the user before we move on.
QtCore.QCoreApplication.processEvents()

# resolve path
# toolkit uses utf-8 encoded strings internally and the After Effects API expects unicode
# so convert the path to ensure filenames containing complex characters are supported
path = self.get_publish_path(sg_publish_data).decode('utf-8')

if self.parent.engine.is_adobe_sequence(path):
frame_range = self.parent.engine.find_sequence_range(path)
if frame_range:
glob_path = re.sub("[\[]?([#@]+|%0\d+d)[\]]?", "*{}".format(frame_range[0]), path)
for each_path in sorted(glob.glob(glob_path)):
path = each_path
break

if not os.path.exists(path):
raise IOError("File not found on disk - '%s'" % path)

if name == _ADD_TO_COMP:
self._add_to_comp(path)
if name == _ADD_TO_PROJECT:
self.parent.engine.import_filepath(path)
finally:
# Set back the original window flags.
for widget, window_flags in top_level_widgets_flags:
if widget.isVisible():
widget.setWindowFlags(window_flags)
widget.show()

###########################################################################
# helper methods
Expand Down