From f24cbab72ac00c6390787374417649ab0deca663 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 03:46:41 +0800 Subject: [PATCH] Add plugin to block .insv files for Insta360Studio compatibility (#1803) --- .../QuickLook.Plugin.InsvBlocker/Plugin.cs | 78 ++++++++++++++++++ .../QuickLook.Plugin.InsvBlocker.csproj | 80 +++++++++++++++++++ .../QuickLook.Plugin.InsvBlocker/README.md | 26 ++++++ QuickLook.sln | 11 +++ 4 files changed, 195 insertions(+) create mode 100644 QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/Plugin.cs create mode 100644 QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/QuickLook.Plugin.InsvBlocker.csproj create mode 100644 QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/README.md diff --git a/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/Plugin.cs new file mode 100644 index 0000000..9dafc70 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/Plugin.cs @@ -0,0 +1,78 @@ +// Copyright © 2017-2025 QL-Win Contributors +// +// This file is part of QuickLook program. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using QuickLook.Common.Plugin; +using System; +using System.IO; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; + +namespace QuickLook.Plugin.InsvBlocker; + +public class Plugin : IViewer +{ + // Very high priority to ensure this plugin is checked before any other plugins + // This prevents QuickLook from handling .insv files, allowing Insta360Studio's QuickLook to handle them instead + public int Priority => int.MaxValue; + + public void Init() + { + } + + public bool CanHandle(string path) + { + // Match .insv files (Insta360 panoramic video files) + if (Directory.Exists(path)) + return false; + + return path.EndsWith(".insv", StringComparison.OrdinalIgnoreCase); + } + + public void Prepare(string path, ContextObject context) + { + // Set a minimal window size (1x1 pixels) to make the window as small as possible + // This window will be closed immediately in View() before becoming visible + context.PreferredSize = new Size { Width = 1, Height = 1 }; + } + + public void View(string path, ContextObject context) + { + // Create an empty text block as content (required to avoid errors) + var textBlock = new TextBlock + { + Text = "", + Visibility = Visibility.Collapsed + }; + context.ViewerContent = textBlock; + context.IsBusy = false; + + // Close the window immediately using Send priority for immediate execution + // This prevents the window from becoming visible to the user + Application.Current?.Dispatcher?.BeginInvoke(new Action(() => + { + if (context.Source is Window window) + { + window.Close(); + } + }), DispatcherPriority.Send); + } + + public void Cleanup() + { + } +} diff --git a/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/QuickLook.Plugin.InsvBlocker.csproj b/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/QuickLook.Plugin.InsvBlocker.csproj new file mode 100644 index 0000000..b970ad2 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/QuickLook.Plugin.InsvBlocker.csproj @@ -0,0 +1,80 @@ + + + + Library + net462 + QuickLook.Plugin.InsvBlocker + QuickLook.Plugin.InsvBlocker + 512 + false + true + latest + false + false + false + MinimumRecommendedRules.ruleset + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D} + + + + true + full + false + ..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\ + DEBUG;TRACE + x86 + prompt + MinimumRecommendedRules.ruleset + + + + pdbonly + true + ..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\ + TRACE + x86 + prompt + MinimumRecommendedRules.ruleset + + + + true + full + false + ..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\ + DEBUG;TRACE + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + + pdbonly + true + ..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\ + TRACE + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95} + QuickLook.Common + False + + + + + + Properties\GitVersion.cs + + + + diff --git a/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/README.md b/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/README.md new file mode 100644 index 0000000..b9f9673 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/README.md @@ -0,0 +1,26 @@ +# QuickLook.Plugin.InsvBlocker + +This plugin prevents QuickLook from handling `.insv` files (Insta360 panoramic video files). + +## Purpose + +Insta360Studio has its own QuickLook application with the same name and activation method (pressing spacebar). When both applications are installed, pressing space on `.insv` files would cause both QuickLook windows to appear, creating a conflict. + +This plugin solves that issue by having QuickLook claim the file (via high priority) but immediately close without displaying anything, allowing Insta360Studio's QuickLook to handle the file instead. + +## Implementation + +- **Priority**: `int.MaxValue` (highest priority, checked before all other plugins) +- **Behavior**: + - Returns `true` for `CanHandle()` on files with `.insv` extension + - Sets minimal window size (1x1 pixels) in `Prepare()` + - Closes the window immediately in `View()` using `DispatcherPriority.Send` + +## Technical Details + +The plugin prevents the QuickLook window from becoming visible by: +1. Matching `.insv` files with highest priority +2. Setting a minimal window size to reduce visual impact if window briefly appears +3. Closing the window immediately after content is set, before it becomes visible to the user + +This approach ensures that Insta360Studio's QuickLook can handle the file without interference. diff --git a/QuickLook.sln b/QuickLook.sln index 183d1e9..6b53f20 100644 --- a/QuickLook.sln +++ b/QuickLook.sln @@ -89,6 +89,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.HelixViewe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.MediaInfoViewer", "QuickLook.Plugin\QuickLook.Plugin.MediaInfoViewer\QuickLook.Plugin.MediaInfoViewer.csproj", "{B0054A16-472E-44AC-BA40-349303E524FF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.InsvBlocker", "QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\QuickLook.Plugin.InsvBlocker.csproj", "{A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -289,6 +291,14 @@ Global {B0054A16-472E-44AC-BA40-349303E524FF}.Release|Any CPU.Build.0 = Release|Any CPU {B0054A16-472E-44AC-BA40-349303E524FF}.Release|x64.ActiveCfg = Release|Any CPU {B0054A16-472E-44AC-BA40-349303E524FF}.Release|x64.Build.0 = Release|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Debug|x64.ActiveCfg = Debug|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Debug|x64.Build.0 = Debug|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Release|Any CPU.Build.0 = Release|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Release|x64.ActiveCfg = Release|Any CPU + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -315,6 +325,7 @@ Global {B4F7C88D-C79D-49E7-A1FB-FB69CF72585F} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} {311E6E78-3A5B-4E51-802A-5755BD5F9F97} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} {B0054A16-472E-44AC-BA40-349303E524FF} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} + {A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D3761C32-8C5F-498A-892B-3B0882994B62}