diff --git a/client/ayon_core/hooks/pre_non_python_host_launch.py b/client/ayon_core/hooks/pre_non_python_host_launch.py index fed4c99447..3d3c24b308 100644 --- a/client/ayon_core/hooks/pre_non_python_host_launch.py +++ b/client/ayon_core/hooks/pre_non_python_host_launch.py @@ -17,7 +17,7 @@ class NonPythonHostHook(PreLaunchHook): python script which launch the host. For these cases it is necessary to prepend python (or ayon) executable and script path before application's. """ - app_groups = {"harmony", "photoshop", "aftereffects"} + app_groups = {"harmony", "aftereffects"} order = 20 launch_types = {LaunchTypes.local} diff --git a/client/ayon_core/hosts/photoshop/__init__.py b/client/ayon_core/hosts/photoshop/__init__.py index 0c79afaab8..cf21b7df75 100644 --- a/client/ayon_core/hosts/photoshop/__init__.py +++ b/client/ayon_core/hosts/photoshop/__init__.py @@ -1,10 +1,12 @@ from .addon import ( PHOTOSHOP_ADDON_ROOT, PhotoshopAddon, + get_launch_script_path, ) __all__ = ( "PHOTOSHOP_ADDON_ROOT", "PhotoshopAddon", + "get_launch_script_path", ) diff --git a/client/ayon_core/hosts/photoshop/addon.py b/client/ayon_core/hosts/photoshop/addon.py index 28833121c4..65fe6a7cd1 100644 --- a/client/ayon_core/hosts/photoshop/addon.py +++ b/client/ayon_core/hosts/photoshop/addon.py @@ -20,3 +20,17 @@ class PhotoshopAddon(AYONAddon, IHostAddon): def get_workfile_extensions(self): return [".psd", ".psb"] + + def get_launch_hook_paths(self, app): + if app.host_name != self.host_name: + return [] + return [ + os.path.join(PHOTOSHOP_ADDON_ROOT, "hooks") + ] + + +def get_launch_script_path(): + return os.path.join( + PHOTOSHOP_ADDON_ROOT, "api", "launch_script.py" + ) + diff --git a/client/ayon_core/hosts/photoshop/hooks/pre_launch_args.py b/client/ayon_core/hosts/photoshop/hooks/pre_launch_args.py new file mode 100644 index 0000000000..0689a6c2f0 --- /dev/null +++ b/client/ayon_core/hosts/photoshop/hooks/pre_launch_args.py @@ -0,0 +1,95 @@ +import os +import platform +import subprocess + +from ayon_core.lib import get_ayon_launcher_args +from ayon_core.lib.applications import ( + PreLaunchHook, + LaunchTypes, +) +from ayon_core.hosts.photoshop import get_launch_script_path + + +def get_launch_kwargs(kwargs): + """Explicit setting of kwargs for Popen for Photoshop. + + Expected behavior + - ayon_console opens window with logs + - ayon has stdout/stderr available for capturing + + Args: + kwargs (Union[dict, None]): Current kwargs or None. + + """ + if kwargs is None: + kwargs = {} + + if platform.system().lower() != "windows": + return kwargs + + executable_path = os.environ.get("AYON_EXECUTABLE") + + executable_filename = "" + if executable_path: + executable_filename = os.path.basename(executable_path) + + is_gui_executable = "ayon_console" not in executable_filename + if is_gui_executable: + kwargs.update({ + "creationflags": subprocess.CREATE_NO_WINDOW, + "stdout": subprocess.DEVNULL, + "stderr": subprocess.DEVNULL + }) + else: + kwargs.update({ + "creationflags": subprocess.CREATE_NEW_CONSOLE + }) + return kwargs + + +class PhotoshopPrelaunchHook(PreLaunchHook): + """Launch arguments preparation. + + Hook add python executable and script path to Photoshop implementation + before Photoshop executable and add last workfile path to launch arguments. + + Existence of last workfile is checked. If workfile does not exists tries + to copy templated workfile from predefined path. + """ + app_groups = {"photoshop"} + + order = 20 + launch_types = {LaunchTypes.local} + + def execute(self): + # Pop executable + executable_path = self.launch_context.launch_args.pop(0) + + # Pop rest of launch arguments - There should not be other arguments! + remainders = [] + while self.launch_context.launch_args: + remainders.append(self.launch_context.launch_args.pop(0)) + + script_path = get_launch_script_path() + + new_launch_args = get_ayon_launcher_args( + "run", script_path, executable_path + ) + # Add workfile path if exists + workfile_path = self.data["last_workfile_path"] + if ( + self.data.get("start_last_workfile") + and workfile_path + and os.path.exists(workfile_path) + ): + new_launch_args.append(workfile_path) + + # Append as whole list as these arguments should not be separated + self.launch_context.launch_args.append(new_launch_args) + + if remainders: + self.launch_context.launch_args.extend(remainders) + + self.launch_context.kwargs = get_launch_kwargs( + self.launch_context.kwargs + )