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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to Aperture Image Viewer are documented here. The format fol

## [Unreleased]

## [0.8.4-beta1] - 2026-08-21

### Fixed
- **Tile-pane Up/Down** move in the same visual column (Explorer-style), including
across date-section headers, instead of jumping by linear item index. An empty
cell (short last row) lands on the nearest tile in that column, then the nearest
in the row — not a section header and not a random index.
- **PageUp/PageDown** scroll roughly one viewport (regardless of zoom / tile size)
and keep the selection in the same column at the same screen Y. They no longer
skip N items or jump to a date-section header.
- **Tab / Shift+Tab** cycle only the folder tree and the tile pane, do not change
either pane's selection, and skip the ribbon (hamburger / command bar / search).
Search stays on `/` and Ctrl+F.

## [0.8.3-beta1] - 2026-08-21

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion src/Aperture.App/Aperture.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<UseWPF>true</UseWPF>
<ApplicationIcon>Assets\aperture.ico</ApplicationIcon>
<AssemblyName>Aperture</AssemblyName>
<Version>0.8.3-beta1</Version>
<Version>0.8.4-beta1</Version>
<AssemblyTitle>Aperture Image Viewer</AssemblyTitle>
<Product>Aperture Image Viewer</Product>
<Description>A fast local image &amp; video browser for Windows.</Description>
Expand Down
9 changes: 9 additions & 0 deletions src/Aperture.App/LibraryPaneFocus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ internal enum Hit
public static bool ShouldFocusContentsPane(DependencyObject? originalSource, IInputElement? currentFocus) =>
ShouldFocusContentsPane(Classify(originalSource, currentFocus));

/// <summary>
/// True when keyboard focus is arriving from outside a pane onto an item
/// that is not the current selection. WPF <see cref="ListBox"/> /
/// <see cref="TreeView"/> often focus (and therefore select) the first
/// item on entry — redirect so Tab does not change the pane's selection.
/// </summary>
public static bool ShouldKeepExistingSelection(bool fromOutside, bool newFocusIsItem, bool newFocusIsSelected) =>
fromOutside && newFocusIsItem && !newFocusIsSelected;

public static Hit Classify(DependencyObject? originalSource, IInputElement? currentFocus)
{
// A dialog keeps focus even if the click somehow reached the pane
Expand Down
27 changes: 18 additions & 9 deletions src/Aperture.App/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,12 @@

<!-- Toolbar -->
<Border DockPanel.Dock="Top" Background="{StaticResource Panel}" BorderBrush="{StaticResource Line}"
BorderThickness="0,0,0,1">
BorderThickness="0,0,0,1" KeyboardNavigation.TabNavigation="None">
<DockPanel Margin="12,10">
<!-- Settings (right) -->
<ToggleButton x:Name="SettingsToggle" DockPanel.Dock="Right" Content="☰"
FontSize="16" Padding="12,4" Style="{StaticResource ToolToggle}" Margin="6,0,0,0"
IsTabStop="False"
ToolTip="Menu" />

<!-- Search (right, left of settings) -->
Expand All @@ -314,12 +315,13 @@
</TextBlock>
<TextBox x:Name="SearchBox" Background="Transparent" BorderThickness="0"
VerticalContentAlignment="Center" Margin="7,0,26,0" FontSize="12"
IsTabStop="False"
GotKeyboardFocus="OnSearchFocus" LostKeyboardFocus="OnSearchBlur"
KeyDown="OnSearchKeyDown"
Text="{Binding SearchInput, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="✕" Command="{Binding ClearSearchCommand}" HorizontalAlignment="Right"
Width="24" Background="Transparent" BorderThickness="0" Foreground="{StaticResource Muted}"
Cursor="Hand" />
IsTabStop="False" Cursor="Hand" />
</Grid>
</Border>

Expand Down Expand Up @@ -525,7 +527,7 @@

<!-- Status bar -->
<Border DockPanel.Dock="Bottom" Background="{StaticResource Panel}" BorderBrush="{StaticResource Line}"
BorderThickness="0,1,0,0">
BorderThickness="0,1,0,0" KeyboardNavigation.TabNavigation="None">
<Grid Margin="12,6">
<TextBlock Text="{Binding StatusText}" Foreground="{StaticResource Ink}" FontSize="12"
VerticalAlignment="Center" />
Expand Down Expand Up @@ -571,14 +573,14 @@

<!-- Roots pane -->
<Border Grid.Column="0" Background="{StaticResource CanvasPanel}" BorderBrush="{StaticResource CanvasLine}"
BorderThickness="0,0,1,0">
BorderThickness="0,0,1,0" KeyboardNavigation.TabNavigation="Once">
<DockPanel>
<!-- Libraries: a saved view over one or more folders. Only the built-in "Everything"
(the union of every included folder) exists for now; add/remove comes later. -->
<TextBlock DockPanel.Dock="Top" Text="LIBRARIES" Foreground="{StaticResource CanvasMuted}"
FontSize="11" FontWeight="SemiBold" Margin="14,12,14,6" />
<Button x:Name="EverythingButton" DockPanel.Dock="Top" Command="{Binding NavigateHomeCommand}"
Margin="8,0,8,2" KeyboardNavigation.TabIndex="0" PreviewKeyDown="OnEverythingKeyDown"
Margin="8,0,8,2" KeyboardNavigation.TabIndex="0"
HorizontalContentAlignment="Stretch" Cursor="Hand" Padding="0" BorderThickness="0"
Foreground="{StaticResource CanvasInk}" FontSize="14"
ToolTip="Show everything across all folders">
Expand Down Expand Up @@ -616,7 +618,9 @@
<TreeView x:Name="FolderTreeView" ItemsSource="{Binding FolderTree}"
BorderThickness="0" Background="Transparent" Foreground="{StaticResource CanvasInk}"
FontSize="14"
SelectedItemChanged="OnTreeSelectedChanged" PreviewKeyDown="OnTreeKeyDown">
KeyboardNavigation.TabNavigation="Once"
SelectedItemChanged="OnTreeSelectedChanged" PreviewKeyDown="OnTreeKeyDown"
PreviewGotKeyboardFocus="OnTreePreviewGotKeyboardFocus">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
Expand Down Expand Up @@ -749,7 +753,7 @@
</Border>

<GridSplitter Grid.Column="1" Width="4" HorizontalAlignment="Center" VerticalAlignment="Stretch"
Background="Transparent" />
Background="Transparent" Focusable="False" IsTabStop="False" />

<!-- Thumbnail grid + preview pane; cells/splitter configured in code (ConfigurePreviewLayout) -->
<Grid x:Name="ContentGrid" Grid.Column="2">
Expand All @@ -763,10 +767,12 @@
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
SelectionMode="Extended"
Focusable="True"
KeyboardNavigation.TabNavigation="Once"
SelectionChanged="OnGridSelectionChanged"
PreviewMouseRightButtonDown="OnGridRightButtonDown"
PreviewMouseLeftButtonDown="OnGridPreviewLeftDown"
PreviewMouseMove="OnGridPreviewMove"
PreviewGotKeyboardFocus="OnGridPreviewGotKeyboardFocus"
Background="{StaticResource CanvasBg}" BorderThickness="0" Padding="6"
ItemContainerStyle="{StaticResource TileContainer}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Expand Down Expand Up @@ -958,12 +964,14 @@
</Grid>

<!-- Drag handle between the browser and the preview (left edge for right-dock, top for bottom) -->
<GridSplitter x:Name="PreviewSplitter" Visibility="Collapsed" Background="{StaticResource CanvasLine}" />
<GridSplitter x:Name="PreviewSplitter" Visibility="Collapsed" Background="{StaticResource CanvasLine}"
Focusable="False" IsTabStop="False" />

<!-- Preview / inspector pane (docks right or bottom; cell + size set in ConfigurePreviewLayout) -->
<Border x:Name="PreviewPane" Visibility="Collapsed"
Background="{StaticResource CanvasPanel}"
BorderBrush="{StaticResource CanvasLine}" BorderThickness="1">
BorderBrush="{StaticResource CanvasLine}" BorderThickness="1"
KeyboardNavigation.TabNavigation="None">
<DockPanel>
<Grid DockPanel.Dock="Top" Margin="14,12,10,10">
<TextBlock Text="PREVIEW" Foreground="{StaticResource CanvasMuted}" FontSize="11" FontWeight="SemiBold"
Expand Down Expand Up @@ -1092,6 +1100,7 @@

<!-- Quick-look overlay -->
<Grid x:Name="QuickLookOverlay" Background="#EE0E1014" MouseDown="OnQuickLookBackgroundClick"
KeyboardNavigation.TabNavigation="None"
Visibility="{Binding QuickLookOpen, Converter={StaticResource BoolToVis}}">
<!-- Transparent hit-target over the central image area, so the tile context menu
(right-click) and double-click-to-open work regardless of how the image letterboxes.
Expand Down
Loading
Loading