From bedb145ee1413482763707fe73787b622cb52cbf Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sat, 13 Jun 2026 16:08:40 +0800
Subject: [PATCH] Fix Finder tab space activation

---
 C1.source/Sources/Aligner/QuickSwitchRootView.swift |  131 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 122 insertions(+), 9 deletions(-)

diff --git a/C1.source/Sources/Aligner/QuickSwitchRootView.swift b/C1.source/Sources/Aligner/QuickSwitchRootView.swift
index d3f89ae..3d16422 100644
--- a/C1.source/Sources/Aligner/QuickSwitchRootView.swift
+++ b/C1.source/Sources/Aligner/QuickSwitchRootView.swift
@@ -226,6 +226,7 @@
         let labelLayer: CATextLayer
         let countLayer: CATextLayer
         let appLayer: CATextLayer
+        let splitAppLayers: [CATextLayer]
         let windowBlocks: [CALayer]
         let fullscreenMarkerLayer: CALayer?
     }
@@ -2540,6 +2541,15 @@
                     color: space.type == .fullscreen ? .labelColor : .secondaryLabelColor,
                     alignment: space.type == .fullscreen ? .center : .left
                 )
+                let splitAppLayers = splitViewAppNames(for: space).map { name in
+                    makeTextLayer(
+                        string: name,
+                        fontSize: 12,
+                        weight: .medium,
+                        color: .labelColor,
+                        alignment: .center
+                    )
+                }
                 let windowBlocks = space.type == .fullscreen
                     ? []
                     : makeWindowBlocks(count: min(space.windowCount, 5), space: space)
@@ -2550,6 +2560,9 @@
                 container.addSublayer(appLayer)
                 if let fullscreenMarkerLayer {
                     container.addSublayer(fullscreenMarkerLayer)
+                }
+                for splitAppLayer in splitAppLayers {
+                    container.addSublayer(splitAppLayer)
                 }
                 for block in windowBlocks {
                     container.addSublayer(block)
@@ -2562,6 +2575,7 @@
                     labelLayer: labelLayer,
                     countLayer: countLayer,
                     appLayer: appLayer,
+                    splitAppLayers: splitAppLayers,
                     windowBlocks: windowBlocks,
                     fullscreenMarkerLayer: fullscreenMarkerLayer
                 )
@@ -2925,6 +2939,9 @@
             ? primaryTextColor
             : secondaryTextColor
         ).cgColor
+        for splitAppLayer in segment.splitAppLayers {
+            splitAppLayer.foregroundColor = primaryTextColor.cgColor
+        }
 
         for block in segment.windowBlocks {
             block.backgroundColor = (isLocked
@@ -3070,21 +3087,52 @@
 
     private func layoutSpaceLaneSegmentContents(_ segment: SpaceLaneSegmentLayers) {
         let bounds = segment.containerLayer.bounds
+        let splitAppNames = splitViewAppNames(for: segment.space)
+        let isSplitView = splitAppNames.count >= 2
         segment.labelLayer.frame = CGRect(x: 10, y: bounds.height - 29, width: max(1, bounds.width - 48), height: 20)
         segment.countLayer.frame = CGRect(x: bounds.width - 34, y: bounds.height - 29, width: 24, height: 20)
+        segment.countLayer.string = isSplitView ? "" : "\(segment.space.windowCount)"
+        segment.countLayer.isHidden = isSplitView
         if segment.space.type == .fullscreen {
             let markerFrame = fullscreenMarkerFrame(in: bounds)
-            segment.appLayer.frame = CGRect(
-                x: 8,
-                y: markerFrame.midY - 8.5,
-                width: max(1, bounds.width - 16),
-                height: 17
-            )
+            segment.appLayer.isHidden = isSplitView
+            if isSplitView {
+                let labelY = markerFrame.midY - 8.5
+                let halfWidth = markerFrame.width / 2
+                for (index, splitAppLayer) in segment.splitAppLayers.enumerated() {
+                    let x = markerFrame.minX + CGFloat(index) * halfWidth
+                    splitAppLayer.isHidden = false
+                    splitAppLayer.frame = CGRect(
+                        x: x + 4,
+                        y: labelY,
+                        width: max(1, halfWidth - 8),
+                        height: 17
+                    )
+                }
+            } else {
+                segment.appLayer.frame = CGRect(
+                    x: 8,
+                    y: markerFrame.midY - 8.5,
+                    width: max(1, bounds.width - 16),
+                    height: 17
+                )
+                for splitAppLayer in segment.splitAppLayers {
+                    splitAppLayer.isHidden = true
+                }
+            }
         } else {
+            segment.appLayer.isHidden = false
             segment.appLayer.frame = CGRect(x: 10, y: 9, width: max(1, bounds.width - 20), height: 17)
+            for splitAppLayer in segment.splitAppLayers {
+                splitAppLayer.isHidden = true
+            }
         }
         if let fullscreenMarkerLayer = segment.fullscreenMarkerLayer {
-            layoutFullscreenMarkerLayer(fullscreenMarkerLayer, in: bounds)
+            layoutFullscreenMarkerLayer(
+                fullscreenMarkerLayer,
+                in: bounds,
+                isSplitView: isSplitView
+            )
         }
 
         let blockGap: CGFloat = 5
@@ -4671,13 +4719,38 @@
         return identifiers.joined(separator: " ")
     }
 
-    private func layoutFullscreenMarkerLayer(_ layer: CALayer, in segmentBounds: CGRect) {
+    private func splitViewAppNames(for space: QuickSwitchSpaceViewModel) -> [String] {
+        guard space.type == .fullscreen else { return [] }
+
+        let names = space.splitViewAppNames
+            .prefix(2)
+            .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
+            .filter { !$0.isEmpty }
+
+        guard names.count >= 2 else { return [] }
+        return names
+    }
+
+    private func layoutFullscreenMarkerLayer(
+        _ layer: CALayer,
+        in segmentBounds: CGRect,
+        isSplitView: Bool = false
+    ) {
         let markerFrame = fullscreenMarkerFrame(in: segmentBounds)
         layer.frame = markerFrame
 
         guard let shapeLayer = layer as? CAShapeLayer else { return }
 
         let bounds = shapeLayer.bounds
+        if isSplitView {
+            let path = CGMutablePath()
+            path.move(to: CGPoint(x: bounds.midX, y: bounds.minY))
+            path.addLine(to: CGPoint(x: bounds.midX, y: bounds.maxY))
+            shapeLayer.path = path
+            shapeLayer.lineCap = .butt
+            return
+        }
+
         let cornerLength = min(12, max(7, min(bounds.width, bounds.height) * 0.28))
         let path = CGMutablePath()
 
@@ -4698,6 +4771,7 @@
         path.addLine(to: CGPoint(x: 0, y: bounds.maxY - cornerLength))
 
         shapeLayer.path = path
+        shapeLayer.lineCap = .round
     }
 
     private func fullscreenMarkerFrame(in segmentBounds: CGRect) -> CGRect {
@@ -5086,6 +5160,8 @@
                 let fullscreenMarkerCenterRatio = fullscreenMarkerFrame.map {
                     Double($0.midY / max(1, segment.containerLayer.bounds.height))
                 }
+                let splitAppNames = splitViewAppNames(for: space)
+                let splitAppLabelFrames = segment.splitAppLayers.map { dictionary(from: $0.frame) }
                 return [
                     "displayUUID": display.displayUUID,
                     "displayLabel": display.displayLabel,
@@ -5094,13 +5170,27 @@
                     "type": spaceTypeName(space.type),
                     "visualStates": visualStates(for: space),
                     "fullscreenMarkerVisible": segment.fullscreenMarkerLayer != nil,
-                    "fullscreenMarkerKind": segment.fullscreenMarkerLayer == nil ? "none" : "cornerBracket",
+                    "fullscreenMarkerKind": fullscreenMarkerKind(
+                        markerLayer: segment.fullscreenMarkerLayer,
+                        splitAppNames: splitAppNames
+                    ),
+                    "fullscreenMarkerPathStyle": fullscreenMarkerPathStyle(
+                        markerLayer: segment.fullscreenMarkerLayer,
+                        splitAppNames: splitAppNames
+                    ),
                     "fullscreenMarkerFrame": fullscreenMarkerFrame.map { dictionary(from: $0) } ?? NSNull(),
                     "fullscreenMarkerCenterRatio": fullscreenMarkerCenterRatio ?? NSNull(),
+                    "splitViewAppNames": splitAppNames,
+                    "splitViewLabelFrames": splitAppLabelFrames,
+                    "splitViewLabelColors": segment.splitAppLayers.map {
+                        colorDictionary(from: $0.foregroundColor)
+                    },
                     "windowBlockCount": segment.windowBlocks.count,
                     "windowBlockColors": segment.windowBlocks.map { colorDictionary(from: $0.backgroundColor) },
                     "windowBlockFrames": segment.windowBlocks.map { dictionary(from: $0.frame) },
                     "labelColor": colorDictionary(from: segment.labelLayer.foregroundColor),
+                    "countText": string(from: segment.countLayer.string),
+                    "countVisible": !segment.countLayer.isHidden && segment.countLayer.opacity > 0,
                     "countColor": colorDictionary(from: segment.countLayer.foregroundColor),
                     "appColor": colorDictionary(from: segment.appLayer.foregroundColor),
                     "fullscreenMarkerStrokeColor": colorDictionary(
@@ -5140,6 +5230,16 @@
         }
     }
 
+    private func fullscreenMarkerKind(markerLayer: CALayer?, splitAppNames: [String]) -> String {
+        guard markerLayer != nil else { return "none" }
+        return splitAppNames.count >= 2 ? "splitViewPair" : "cornerBracket"
+    }
+
+    private func fullscreenMarkerPathStyle(markerLayer: CALayer?, splitAppNames: [String]) -> String {
+        guard markerLayer != nil else { return "none" }
+        return splitAppNames.count >= 2 ? "centerDividerOnly" : "cornerBracket"
+    }
+
     private func visualStates(for space: QuickSwitchSpaceViewModel) -> [String] {
         var states: [String] = []
         if space.isCurrent {
@@ -5162,6 +5262,9 @@
         }
         if space.type == .fullscreen {
             states.append("fullscreen")
+        }
+        if splitViewAppNames(for: space).count >= 2 {
+            states.append("splitView")
         }
         return states
     }
@@ -5188,6 +5291,16 @@
         ]
     }
 
+    private func string(from textLayerValue: Any?) -> String {
+        if let string = textLayerValue as? String {
+            return string
+        }
+        if let attributedString = textLayerValue as? NSAttributedString {
+            return attributedString.string
+        }
+        return ""
+    }
+
     private func colorDictionary(from color: CGColor?) -> [String: Double] {
         guard let color,
               let nsColor = NSColor(cgColor: color)?.usingColorSpace(.deviceRGB)

--
Gitblit v1.9.3