Skip to content
Merged
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
78 changes: 78 additions & 0 deletions QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/Plugin.cs
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

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()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net462</TargetFramework>
<RootNamespace>QuickLook.Plugin.InsvBlocker</RootNamespace>
<AssemblyName>QuickLook.Plugin.InsvBlocker</AssemblyName>
<FileAlignment>512</FileAlignment>
<SignAssembly>false</SignAssembly>
<UseWPF>true</UseWPF>
<LangVersion>latest</LangVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<ProjectGuid>{A1B2C3D4-E5F6-4A5B-9C8D-7E6F5A4B3C2D}</ProjectGuid>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.InsvBlocker\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<ItemGroup>
<Reference Include="WindowsBase" />
<Reference Include="System.ComponentModel.Composition" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\QuickLook.Common\QuickLook.Common.csproj">
<Project>{85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95}</Project>
<Name>QuickLook.Common</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>

<ItemGroup>
<Compile Include="..\..\GitVersion.cs">
<Link>Properties\GitVersion.cs</Link>
</Compile>
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions QuickLook.Plugin/QuickLook.Plugin.InsvBlocker/README.md
Original file line number Diff line number Diff line change
@@ -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.
11 changes: 11 additions & 0 deletions QuickLook.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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}
Expand Down
Loading