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}