Skip to content

Commit d1d118e

Browse files
committed
Tweak widget behavior
1 parent 7c5c105 commit d1d118e

File tree

2 files changed

+57
-35
lines changed

2 files changed

+57
-35
lines changed

Core/Sources/SuggestionWidget/WidgetWindowsController.swift

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ final class WidgetWindowsController: NSObject {
5353
guard let app else { return }
5454
Task { [weak self] in await self?.activate(app) }
5555
}.store(in: &cancellable)
56+
57+
xcodeInspector.$focusedEditor.sink { [weak self] editor in
58+
guard let editor else { return }
59+
Task { [weak self] in await self?.observe(to: editor) }
60+
}.store(in: &cancellable)
5661

5762
xcodeInspector.$completionPanel.sink { [weak self] newValue in
5863
Task { [weak self] in
@@ -160,11 +165,10 @@ final class WidgetWindowsController: NSObject {
160165
function: StaticString = #function,
161166
line: UInt = #line
162167
) async {
163-
let state = store.withState { $0 }
164-
let isChatPanelDetached = state.chatPanelState.chatPanelInASeparateWindow
165-
166168
@Sendable @MainActor
167169
func update() async {
170+
let state = store.withState { $0 }
171+
let isChatPanelDetached = state.chatPanelState.chatPanelInASeparateWindow
168172
guard let widgetLocation = generateWidgetLocation() else { return }
169173
await updatePanelState(widgetLocation)
170174

@@ -275,34 +279,24 @@ private extension WidgetWindowsController {
275279
}
276280

277281
func observe(to app: AppInstanceInspector) async {
282+
Task {
283+
await updateWindowLocation(animated: false, immediately: true)
284+
await updateWindowOpacity(immediately: true)
285+
}
278286
guard let app = app as? XcodeAppInstanceInspector else {
279-
Task {
280-
await updateWindowLocation(animated: false, immediately: true)
281-
await updateWindowOpacity(immediately: true)
282-
}
283287
return
284288
}
285289
let notifications = app.axNotifications
286-
if let focusedEditor = xcodeInspector.focusedEditor {
287-
await observe(to: focusedEditor)
288-
}
289-
290290
let task = Task {
291291
await windows.orderFront()
292292

293293
let documentURL = await MainActor.run { store.withState { $0.focusingDocumentURL } }
294294
for await notification in notifications {
295-
if [.uiElementDestroyed, .created, .xcodeCompletionPanelChanged]
296-
.contains(notification.kind) { continue }
297-
298295
try Task.checkCancellation()
299296

300-
// Hide the widgets before switching to another window/editor
301-
// so the transition looks better.
302-
if [
303-
.focusedUIElementChanged,
304-
.focusedWindowChanged,
305-
].contains(notification.kind) {
297+
/// Hide the widgets before switching to another window/editor
298+
/// so the transition looks better.
299+
func hideWidgetForTransitions() async {
306300
let newDocumentURL = xcodeInspector.realtimeActiveDocumentURL
307301
if documentURL != newDocumentURL {
308302
await send(.panel(.removeDisplayedContent))
@@ -311,23 +305,34 @@ private extension WidgetWindowsController {
311305
await send(.updateFocusingDocumentURL)
312306
}
313307

314-
// update widgets.
315-
if [
316-
.focusedUIElementChanged,
317-
.applicationActivated,
318-
.mainWindowChanged,
319-
.focusedWindowChanged,
320-
].contains(notification.kind) {
308+
func updateWidgetsAndNotifyChangeOfEditor() async {
321309
await updateWindowLocation(animated: false, immediately: false)
322310
await updateWindowOpacity(immediately: false)
323-
if let editor = xcodeInspector.focusedEditor {
324-
await observe(to: editor)
325-
}
326311
await send(.panel(.switchToAnotherEditorAndUpdateContent))
327-
} else {
312+
}
313+
314+
func updateWidgets() async {
328315
await updateWindowLocation(animated: false, immediately: false)
329316
await updateWindowOpacity(immediately: false)
330317
}
318+
319+
switch notification.kind {
320+
case .focusedWindowChanged, .focusedUIElementChanged:
321+
await hideWidgetForTransitions()
322+
await updateWidgetsAndNotifyChangeOfEditor()
323+
case .applicationActivated, .mainWindowChanged:
324+
await updateWidgetsAndNotifyChangeOfEditor()
325+
case .applicationDeactivated,
326+
.moved,
327+
.resized,
328+
.windowMoved,
329+
.windowResized,
330+
.windowMiniaturized,
331+
.windowDeminiaturized:
332+
await updateWidgets()
333+
case .created, .uiElementDestroyed, .xcodeCompletionPanelChanged:
334+
continue
335+
}
331336
}
332337
}
333338

@@ -343,19 +348,31 @@ private extension WidgetWindowsController {
343348
.filter { $0.kind == .scrollPositionChanged }
344349

345350
if #available(macOS 13.0, *) {
346-
for await _ in merge(
351+
for await notification in merge(
347352
selectionRangeChange.debounce(for: Duration.milliseconds(500)),
348353
scroll
349354
) {
350355
guard xcodeInspector.latestActiveXcode != nil else { return }
351356
try Task.checkCancellation()
357+
358+
// for better looking
359+
if notification.kind == .scrollPositionChanged {
360+
await hideSuggestionPanelWindow()
361+
}
362+
352363
await updateWindowLocation(animated: false, immediately: false)
353364
await updateWindowOpacity(immediately: false)
354365
}
355366
} else {
356-
for await _ in merge(selectionRangeChange, scroll) {
367+
for await notification in merge(selectionRangeChange, scroll) {
357368
guard xcodeInspector.latestActiveXcode != nil else { return }
358369
try Task.checkCancellation()
370+
371+
// for better looking
372+
if notification.kind == .scrollPositionChanged {
373+
await hideSuggestionPanelWindow()
374+
}
375+
359376
await updateWindowLocation(animated: false, immediately: false)
360377
await updateWindowOpacity(immediately: false)
361378
}
@@ -373,6 +390,11 @@ extension WidgetWindowsController {
373390
windows.sharedPanelWindow.alphaValue = 0
374391
windows.suggestionPanelWindow.alphaValue = 0
375392
}
393+
394+
@MainActor
395+
func hideSuggestionPanelWindow() {
396+
windows.suggestionPanelWindow.alphaValue = 0
397+
}
376398

377399
func generateWidgetLocation() -> WidgetLocation? {
378400
if let application = xcodeInspector.latestActiveXcode?.appElement {

Tool/Sources/XcodeInspector/XcodeInspector.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,13 @@ public final class XcodeInspector: ObservableObject {
152152
$0.processIdentifier == app.processIdentifier && !$0.isTerminated
153153
}) {
154154
Task { @XcodeInspectorActor in
155-
await self.setActiveXcode(existed)
155+
self.setActiveXcode(existed)
156156
}
157157
} else {
158158
let new = XcodeAppInstanceInspector(runningApplication: app)
159159
Task { @XcodeInspectorActor in
160160
self.xcodes.append(new)
161-
await self.setActiveXcode(new)
161+
self.setActiveXcode(new)
162162
}
163163
}
164164
} else {

0 commit comments

Comments
 (0)