Skip to content

Fix Task Dropdown Crash #1956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 8, 2025
44 changes: 38 additions & 6 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@
6C05A8AF284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C05A8AE284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift */; };
6C05CF9E2CDE8699006AAECD /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 6C05CF9D2CDE8699006AAECD /* CodeEditSourceEditor */; };
6C0617D62BDB4432008C9C42 /* LogStream in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0617D52BDB4432008C9C42 /* LogStream */; };
6C07383B2D284ECA0025CBE3 /* TasksMenuUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C07383A2D284ECA0025CBE3 /* TasksMenuUITests.swift */; };
6C08249C2C556F7400A0751E /* TerminalCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C08249B2C556F7400A0751E /* TerminalCache.swift */; };
6C08249E2C55768400A0751E /* UtilityAreaTerminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C08249D2C55768400A0751E /* UtilityAreaTerminal.swift */; };
6C0824A12C5C0C9700A0751E /* SwiftTerm in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0824A02C5C0C9700A0751E /* SwiftTerm */; };
Expand Down Expand Up @@ -402,6 +403,7 @@
6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F62972E5F300D6D205 /* WindowObserver.swift */; };
6C4E37F62C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4E37F52C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift */; };
6C4E37FC2C73E00700AEE7B5 /* SwiftTerm in Frameworks */ = {isa = PBXBuildFile; productRef = 6C4E37FB2C73E00700AEE7B5 /* SwiftTerm */; };
6C510CB82D2E4639006EBE85 /* XCUITest+waitForNonExistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C510CB72D2E4639006EBE85 /* XCUITest+waitForNonExistence.swift */; };
6C5228B529A868BD00AC48F6 /* Environment+ContentInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */; };
6C53AAD829A6C4FD00EE9ED6 /* SplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */; };
6C578D8129CD294800DC73B2 /* ExtensionActivatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C578D8029CD294800DC73B2 /* ExtensionActivatorView.swift */; };
Expand Down Expand Up @@ -1051,6 +1053,7 @@
66F370332BEE537B00D3B823 /* NonTextFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonTextFileView.swift; sourceTree = "<group>"; };
6C049A362A49E2DB00D42923 /* DirectoryEventStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectoryEventStream.swift; sourceTree = "<group>"; };
6C05A8AE284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WorkspaceDocument+Listeners.swift"; sourceTree = "<group>"; };
6C07383A2D284ECA0025CBE3 /* TasksMenuUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TasksMenuUITests.swift; sourceTree = "<group>"; };
6C08249B2C556F7400A0751E /* TerminalCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalCache.swift; sourceTree = "<group>"; };
6C08249D2C55768400A0751E /* UtilityAreaTerminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaTerminal.swift; sourceTree = "<group>"; };
6C092ED92A53A58600489202 /* EditorLayout+StateRestoration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditorLayout+StateRestoration.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1093,6 +1096,7 @@
6C48D8F32972DB1A00D6D205 /* Env+Window.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Env+Window.swift"; sourceTree = "<group>"; };
6C48D8F62972E5F300D6D205 /* WindowObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowObserver.swift; sourceTree = "<group>"; };
6C4E37F52C73DA5200AEE7B5 /* UtilityAreaTerminalSidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaTerminalSidebar.swift; sourceTree = "<group>"; };
6C510CB72D2E4639006EBE85 /* XCUITest+waitForNonExistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUITest+waitForNonExistence.swift"; sourceTree = "<group>"; };
6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+ContentInsets.swift"; sourceTree = "<group>"; };
6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitView.swift; sourceTree = "<group>"; };
6C578D8029CD294800DC73B2 /* ExtensionActivatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionActivatorView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2705,14 +2709,14 @@
618725A22C29EFE200987354 /* Tasks */ = {
isa = PBXGroup;
children = (
B69D3EE22C5F536B005CF43A /* ActiveTaskView.swift */,
618725A52C29F02500987354 /* DropdownMenuItemStyleModifier.swift */,
618725A72C29F05500987354 /* OptionMenuItemView.swift */,
618725A02C29EFCC00987354 /* SchemeDropDownView.swift */,
618725AA2C29F2C000987354 /* TaskDropDownView.swift */,
B69D3EE02C5F5357005CF43A /* TaskView.swift */,
B69D3EE22C5F536B005CF43A /* ActiveTaskView.swift */,
B69D3EE42C5F54B3005CF43A /* TasksPopoverMenuItem.swift */,
B69D3EE02C5F5357005CF43A /* TaskView.swift */,
618725A32C29F00400987354 /* WorkspaceMenuItemView.swift */,
618725A72C29F05500987354 /* OptionMenuItemView.swift */,
618725A52C29F02500987354 /* DropdownMenuItemStyleModifier.swift */,
);
path = Tasks;
sourceTree = "<group>";
Expand Down Expand Up @@ -2838,6 +2842,22 @@
name = "Recovered References";
sourceTree = "<group>";
};
6C0738382D284EA20025CBE3 /* ActivityViewer */ = {
isa = PBXGroup;
children = (
6C0738392D284EAE0025CBE3 /* Tasks */,
);
path = ActivityViewer;
sourceTree = "<group>";
};
6C0738392D284EAE0025CBE3 /* Tasks */ = {
isa = PBXGroup;
children = (
6C07383A2D284ECA0025CBE3 /* TasksMenuUITests.swift */,
);
path = Tasks;
sourceTree = "<group>";
};
6C092EDC2A53A63E00489202 /* Views */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2948,6 +2968,14 @@
path = Environment;
sourceTree = "<group>";
};
6C510CB62D2E462D006EBE85 /* Extensions */ = {
isa = PBXGroup;
children = (
6C510CB72D2E4639006EBE85 /* XCUITest+waitForNonExistence.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
6C6BD6ED29CD123000235D17 /* Extensions */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3004,6 +3032,7 @@
6C96191E2C3F27E3009733CE /* Features */ = {
isa = PBXGroup;
children = (
6C0738382D284EA20025CBE3 /* ActivityViewer */,
6C96191D2C3F27E3009733CE /* NavigatorArea */,
);
path = Features;
Expand All @@ -3013,10 +3042,11 @@
isa = PBXGroup;
children = (
6CFBA54A2C4E168A00E3A914 /* App.swift */,
6C9619232C3F2809009733CE /* ProjectPath.swift */,
6C9619212C3F27F1009733CE /* Query.swift */,
6C510CB62D2E462D006EBE85 /* Extensions */,
6C96191E2C3F27E3009733CE /* Features */,
6CFBA54E2C4E182100E3A914 /* Other Tests */,
6C9619232C3F2809009733CE /* ProjectPath.swift */,
6C9619212C3F27F1009733CE /* Query.swift */,
);
path = CodeEditUITests;
sourceTree = "<group>";
Expand Down Expand Up @@ -4577,10 +4607,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6C510CB82D2E4639006EBE85 /* XCUITest+waitForNonExistence.swift in Sources */,
6C9619242C3F2809009733CE /* ProjectPath.swift in Sources */,
6CFBA54B2C4E168A00E3A914 /* App.swift in Sources */,
6CFBA54D2C4E16C900E3A914 /* WindowCloseCommandTests.swift in Sources */,
6C9619222C3F27F1009733CE /* Query.swift in Sources */,
6C07383B2D284ECA0025CBE3 /* TasksMenuUITests.swift in Sources */,
6C9619202C3F27E3009733CE /* ProjectNavigatorUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
2 changes: 2 additions & 0 deletions CodeEdit/Features/ActivityViewer/ActivityViewer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@ struct ActivityViewer: View {
.opacity(0.1)
}
}
.accessibilityElement(children: .contain)
.accessibilityLabel("Activity Viewer")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ struct CECircularProgressView: View {
.font(.caption)
}
}
.accessibilityElement()
.accessibilityAddTraits(.updatesFrequently)
.accessibilityValue(
progress != nil ? Text(progress!, format: .percent) : Text("working")
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ struct TaskNotificationView: View {
.padding(.trailing, 3)
.popover(isPresented: $isPresented, arrowEdge: .bottom) {
TaskNotificationsDetailView(taskNotificationHandler: taskNotificationHandler)
}.onTapGesture {
}
.onTapGesture {
self.isPresented.toggle()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SwiftUI
struct OptionMenuItemView: View {
var label: String
var action: () -> Void

var body: some View {
HStack {
Text(label)
Expand All @@ -22,6 +23,11 @@ struct OptionMenuItemView: View {
.onTapGesture {
action()
}
.accessibilityElement()
.accessibilityAction {
action()
}
.accessibilityLabel(label)
}
}

Expand Down
73 changes: 45 additions & 28 deletions CodeEdit/Features/ActivityViewer/Tasks/SchemeDropDownView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ struct SchemeDropDownView: View {
workspaceSettingsManager.settings.project.projectName
}

/// Resolves the name one step further than `workspaceName`.
var workspaceDisplayName: String {
workspaceName.isEmpty
? (workspaceFileManager?.workspaceItem.fileName() ?? "No Project found")
: workspaceName
}

var body: some View {
HStack(spacing: 6) {
Image(systemName: "folder.badge.gearshape")
.imageScale(.medium)
Text(
workspaceName.isEmpty
? (workspaceFileManager?.workspaceItem.fileName() ?? "No Project found")
: workspaceName
)
Text(workspaceDisplayName)
}
.font(.subheadline)
.padding(.trailing, 11.5)
Expand All @@ -54,31 +57,19 @@ struct SchemeDropDownView: View {
self.isHoveringScheme = hovering
})
.instantPopover(isPresented: $isSchemePopOverPresented, arrowEdge: .bottom) {
VStack(alignment: .leading, spacing: 0) {
WorkspaceMenuItemView(
workspaceFileManager: workspaceFileManager,
item: workspaceFileManager?.workspaceItem
)
Divider()
.padding(.vertical, 5)
Group {
OptionMenuItemView(label: "Add Folder...") {
// TODO: Implment Add Folder
print("NOT IMPLEMENTED")
}
OptionMenuItemView(label: "Workspace Settings...") {
NSApp.sendAction(
#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil
)
}
}
}
.font(.subheadline)
.padding(5)
.frame(minWidth: 215)
popoverContent
}
.onTapGesture {
self.isSchemePopOverPresented.toggle()
isSchemePopOverPresented.toggle()
}
.accessibilityElement(children: .combine)
.accessibilityAddTraits(.isButton)
.accessibilityIdentifier("SchemeDropdown")
.accessibilityValue(workspaceDisplayName)
.accessibilityLabel("Active Scheme")
.accessibilityHint("Open the active scheme menu")
.accessibilityAction {
isSchemePopOverPresented.toggle()
}
}

Expand All @@ -97,6 +88,32 @@ struct SchemeDropDownView: View {
.font(.system(size: 8, weight: .semibold, design: .default))
.padding(.top, 0.5)
}

@ViewBuilder var popoverContent: some View {
VStack(alignment: .leading, spacing: 0) {
WorkspaceMenuItemView(
workspaceFileManager: workspaceFileManager,
item: workspaceFileManager?.workspaceItem
)
Divider()
.padding(.vertical, 5)
Group {
OptionMenuItemView(label: "Add Folder...") {
// TODO: Implment Add Folder
print("NOT IMPLEMENTED")
}
.disabled(true)
OptionMenuItemView(label: "Workspace Settings...") {
NSApp.sendAction(
#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil
)
}
}
}
.font(.subheadline)
.padding(5)
.frame(minWidth: 215)
}
}

// #Preview {
Expand Down
15 changes: 13 additions & 2 deletions CodeEdit/Features/ActivityViewer/Tasks/TaskDropDownView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,21 @@ struct TaskDropDownView: View {
.onHover { hovering in
self.isHoveringTasks = hovering
}
.instantPopover(isPresented: $isTaskPopOverPresented, arrowEdge: .bottom) {
.instantPopover(isPresented: $isTaskPopOverPresented, arrowEdge: .top) {
taskPopoverContent
}
.onTapGesture {
self.isTaskPopOverPresented.toggle()
}
.accessibilityElement(children: .combine)
.accessibilityAddTraits(.isButton)
.accessibilityIdentifier("TaskDropdown")
.accessibilityValue(taskManager.selectedTask?.name ?? "Create Tasks")
.accessibilityLabel("Active Task")
.accessibilityHint("Open the active task menu")
.accessibilityAction {
isTaskPopOverPresented = true
}
}

private var backgroundColor: some View {
Expand Down Expand Up @@ -71,7 +80,9 @@ struct TaskDropDownView: View {
VStack(alignment: .leading, spacing: 0) {
if !taskManager.availableTasks.isEmpty {
ForEach(taskManager.availableTasks, id: \.id) { task in
TasksPopoverMenuItem(taskManager: taskManager, task: task)
TasksPopoverMenuItem(taskManager: taskManager, task: task) {
isTaskPopOverPresented = false
}
}
Divider()
.padding(.vertical, 5)
Expand Down
2 changes: 2 additions & 0 deletions CodeEdit/Features/ActivityViewer/Tasks/TaskView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ struct TaskView: View {
.frame(width: 5, height: 5)
.padding(.trailing, 2.5)
}
.accessibilityElement()
.accessibilityLabel(task.name)
}
}
21 changes: 14 additions & 7 deletions CodeEdit/Features/ActivityViewer/Tasks/TasksPopoverMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

import SwiftUI

/// - Note: This view **cannot** use the `dismiss` environment value to dismiss the sheet. It has to negate the boolean
/// value that presented it initially.
/// See ``SwiftUI/View/instantPopover(isPresented:arrowEdge:content:)``
struct TasksPopoverMenuItem: View {
@Environment(\.dismiss)
private var dismiss

@ObservedObject var taskManager: TaskManager
var task: CETask
var dismiss: () -> Void

var body: some View {
HStack(spacing: 5) {
Expand All @@ -22,11 +23,12 @@ struct TasksPopoverMenuItem: View {
.padding(.vertical, 4)
.padding(.horizontal, 8)
.modifier(DropdownMenuItemStyleModifier())
.onTapGesture {
taskManager.selectedTaskID = task.id
dismiss()
}
.onTapGesture(perform: selectAction)
.clipShape(RoundedRectangle(cornerRadius: 5))
.accessibilityElement()
.accessibilityLabel(task.name)
.accessibilityAction(.default, selectAction)
.accessibilityAddTraits(taskManager.selectedTaskID == task.id ? [.isSelected] : [])
}

private var selectionIndicator: some View {
Expand All @@ -52,4 +54,9 @@ struct TasksPopoverMenuItem: View {
}
}
}

private func selectAction() {
taskManager.selectedTaskID = task.id
dismiss()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ struct WorkspaceMenuItemView: View {
.padding(.vertical, 4)
.padding(.horizontal, 8)
.modifier(DropdownMenuItemStyleModifier())
.onTapGesture { }
.onTapGesture { } // add accessibility action when this is filled in
.clipShape(RoundedRectangle(cornerRadius: 5))
.accessibilityElement()
.accessibilityLabel(item?.name ?? "")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct AddCETaskView: View {
}
.padding()
}
.accessibilityIdentifier("AddTaskView")
}

}
Expand Down
Loading