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
2 changes: 1 addition & 1 deletion Examples/ClientSideResizeChrome/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ enum ClientSideResizeChrome {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID):
case .redrawRequested(.window(let windowID)):
if let controller = await registry.controller(for: windowID) {
try await controller.redrawIfNeeded()
}
Expand Down
2 changes: 1 addition & 1 deletion Examples/CursorAnimationSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ enum CursorAnimationSmoke {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == window.id:
case .redrawRequested(.window(let windowID)) where windowID == window.id:
try await redraw(window)
case .windowCloseRequested(let windowID) where windowID == window.id:
await window.close()
Expand Down
2 changes: 1 addition & 1 deletion Examples/CursorPolicySmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ enum CursorPolicySmoke {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == window.id:
case .redrawRequested(.window(let windowID)) where windowID == window.id:
try await redraw(window)
case .windowOutputsChanged(let outputs) where outputs.windowID == window.id:
log("window outputs=\(outputs.outputs)")
Expand Down
2 changes: 1 addition & 1 deletion Examples/CustomCursorSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ enum CustomCursorSmoke {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == window.id:
case .redrawRequested(.window(let windowID)) where windowID == window.id:
try await redraw(window)
case .windowCloseRequested(let windowID) where windowID == window.id:
await window.close()
Expand Down
2 changes: 1 addition & 1 deletion Examples/DataTransferSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ enum DataTransferSmoke {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == window.id:
case .redrawRequested(.window(let windowID)) where windowID == window.id:
try await redrawIfNeeded(window: window, state: state)
case .windowCloseRequested(let windowID) where windowID == window.id:
await window.close()
Expand Down
4 changes: 2 additions & 2 deletions Examples/FrameworkHostSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ enum FrameworkHostSmoke {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == window.id:
case .redrawRequested(.window(let windowID)) where windowID == window.id:
try await loop.redrawIfNeeded()
case .windowCloseRequested(let windowID) where windowID == window.id:
await window.close()
Expand All @@ -84,7 +84,7 @@ enum FrameworkHostSmoke {
break
case .diagnostic(let diagnostic):
log("display diagnostic \(diagnostic)")
case .popupDismissed, .popupClosed, .popupRedrawRequested, .outputChanged,
case .popupDismissed, .popupClosed, .outputChanged,
.outputRemoved, .windowCloseRequested, .windowClosed, .redrawRequested,
.windowOutputsChanged, .keyboardShortcutsInhibitorChanged:
break
Expand Down
2 changes: 1 addition & 1 deletion Examples/GraphicsPreviewManagedGPUClear/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ enum GraphicsPreviewManagedGPUClear {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == backing.id:
case .redrawRequested(.window(let windowID)) where windowID == backing.id:
_ = try await submitClearFrame(
backing: backing,
state: state,
Expand Down
2 changes: 1 addition & 1 deletion Examples/KeyboardShortcutsInhibitSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ enum KeyboardShortcutsInhibitSmoke {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
switch event {
case .redrawRequested(let windowID) where windowID == window.id:
case .redrawRequested(.window(let windowID)) where windowID == window.id:
try await window.redraw(draw)
case .windowCloseRequested(let windowID) where windowID == window.id:
await window.close()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import WaylandClient

@main
enum ManagedSurfacePresentationSmoke {
static func main() async throws {
try await WaylandDisplay.withConnection(
applicationID: "org.waylandclientkit.ManagedSurfacePresentationSmoke",
eventStreamConfiguration: try EventStreamConfiguration(
eventCapacity: 128,
inputEventCapacity: 32,
textInputEventCapacity: 16,
dataTransferEventCapacity: 16,
presentationEventCapacity: 64
)
) { display in
try await ManagedSurfaceSmokeRun(display: display).execute()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import WaylandClient

extension ManagedSurfaceSmokeRun {
func presentWindow(_ window: Window, requestsFeedback: Bool) async throws {
var rootEvents = display.events.makeAsyncIterator()
var feedback = window.presentationEvents.makeAsyncIterator()
let outcome = try await retryPresentation(label: "window initial presentation") {
try await window.show(requestPresentationFeedback: requestsFeedback) { frame in
drawManagedSurfaceFrame(frame, color: 0x0030_6090)
}
}
try requirePresented(outcome, label: "window initial presentation")
if requestsFeedback {
try await requireRootFeedback(
from: &rootEvents,
surface: .window(window.id),
label: "window"
)
try await requireFeedback(from: &feedback, label: "window")
}
print("window initial presentation: presented")
}

func presentPopup(_ popup: PopupSurface, requestsFeedback: Bool) async throws {
var rootEvents = display.events.makeAsyncIterator()
var feedback = popup.presentationEvents.makeAsyncIterator()
let outcome = try await retryPresentation(label: "popup initial presentation") {
try await popup.show(
requestPresentationFeedback: requestsFeedback,
preparing: { reservation in reservation.id },
{ _, frame in drawManagedSurfaceFrame(frame, color: 0x0080_4080) }
)
}
try requirePresented(outcome, label: "popup initial presentation")
if requestsFeedback {
try await requireRootFeedback(
from: &rootEvents,
surface: .popup(popup.id),
label: "popup"
)
try await requireFeedback(from: &feedback, label: "popup")
}
print("popup initial presentation: presented")
}

func presentSubsurface(
_ subsurface: Subsurface,
label: String,
color: UInt32,
requestsFeedback: Bool
) async throws {
var rootEvents = display.events.makeAsyncIterator()
var feedback = subsurface.presentationEvents.makeAsyncIterator()
let outcome = try await retryPresentation(label: label) {
try await subsurface.show(
requestPresentationFeedback: requestsFeedback,
preparing: { reservation in reservation.id },
{ _, frame in drawManagedSurfaceFrame(frame, color: color) }
)
}
try requirePresented(outcome, label: label)
if requestsFeedback {
try await requireRootFeedback(
from: &rootEvents,
surface: .subsurface(subsurface.identity),
label: label
)
try await requireFeedback(from: &feedback, label: label)
}
print("\(label): presented")
}

private func requirePresented(
_ outcome: SoftwarePresentationOutcome,
label: String
) throws {
guard outcome == .presented else {
throw ManagedSurfaceSmokeError.unexpectedPresentationOutcome(label, outcome)
}
}

func retryPresentation(
label: String,
operation: () async throws -> SoftwarePresentationOutcome
) async throws -> SoftwarePresentationOutcome {
var latestOutcome = SoftwarePresentationOutcome.deferred
for _ in 0..<8 {
latestOutcome = try await operation()
switch latestOutcome {
case .presented:
return latestOutcome
case .superseded, .deferred:
try await Task.sleep(for: .milliseconds(10))
case .closed:
throw ManagedSurfaceSmokeError.unexpectedPresentationOutcome(
label,
latestOutcome
)
}
}
return latestOutcome
}

private func requireFeedback(
from iterator: inout ManagedSurfacePresentationEvents.AsyncIterator,
label: String
) async throws {
guard let feedback = try await iterator.next() else {
throw ManagedSurfaceSmokeError.presentationStreamEnded(label)
}
print("\(label) feedback: \(feedback)")
}

private func requireRootFeedback(
from iterator: inout DisplayEventsIterator,
surface: ManagedSurfaceIdentity,
label: String
) async throws {
while let event = try await iterator.next() {
if case .presentation(let presentation) = event,
presentation.surface == surface
{
print("\(label) root feedback: \(presentation.feedback)")
return
}
}
throw ManagedSurfaceSmokeError.eventStreamEnded("\(label) root feedback")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import WaylandClient

extension ManagedSurfaceSmokeRun {
func routeRedraw(for window: Window, color: UInt32) async throws {
let skipsRoutingEvent = CommandLine.arguments.contains("--skip-redraw-routing")
var events = display.events.makeAsyncIterator()
try await window.requestRedraw()
if skipsRoutingEvent {
try await Task.sleep(for: .milliseconds(20))
} else {
try await requireRedraw(
from: &events,
surface: .window(window.id),
label: "window redraw"
)
}
let outcome = try await retryPresentation(label: "window redraw") {
try await window.redraw { frame in
drawManagedSurfaceFrame(frame, color: color)
}
}
try requireRedrawPresented(outcome, label: "window redraw")
print("redraw routing: window")
}

func routeRedraw(for popup: PopupSurface, color: UInt32) async throws {
let skipsRoutingEvent = CommandLine.arguments.contains("--skip-redraw-routing")
var events = display.events.makeAsyncIterator()
try await popup.requestRedraw()
if skipsRoutingEvent {
try await Task.sleep(for: .milliseconds(20))
} else {
try await requireRedraw(
from: &events,
surface: .popup(popup.id),
label: "popup redraw"
)
}
let outcome = try await retryPresentation(label: "popup redraw") {
try await popup.redraw { frame in
drawManagedSurfaceFrame(frame, color: color)
}
}
try requireRedrawPresented(outcome, label: "popup redraw")
print("redraw routing: popup")
}

func routeRedraw(for subsurface: Subsurface, color: UInt32) async throws {
let skipsRoutingEvent = CommandLine.arguments.contains("--skip-redraw-routing")
var events = display.events.makeAsyncIterator()
try await subsurface.requestRedraw()
if skipsRoutingEvent {
try await Task.sleep(for: .milliseconds(20))
} else {
try await requireRedraw(
from: &events,
surface: .subsurface(subsurface.identity),
label: "subsurface redraw"
)
}
let outcome = try await retryPresentation(label: "subsurface redraw") {
try await subsurface.redraw { frame in
drawManagedSurfaceFrame(frame, color: color)
}
}
try requireRedrawPresented(outcome, label: "subsurface redraw")
print("redraw routing: \(subsurface.identity)")
}

func finishPopup(_ popup: PopupSurface) async throws {
var events = display.events.makeAsyncIterator()
if CommandLine.arguments.contains("--interactive-dismissal") {
print("popup dismissal: click outside the popup")
while let event = try await events.next() {
if case .popupDismissed(let lifecycle) = event,
lifecycle.popup == popup.id
{
print("popup dismissal: compositor event observed")
await popup.close()
return
}
}
throw ManagedSurfaceSmokeError.eventStreamEnded("popup dismissal")
}

await popup.close()
while let event = try await events.next() {
if case .popupClosed(let lifecycle) = event,
lifecycle.popup == popup.id
{
print("popup cleanup: explicit close observed")
return
}
}
throw ManagedSurfaceSmokeError.eventStreamEnded("popup close")
}

private func requireRedraw(
from iterator: inout DisplayEventsIterator,
surface: ManagedSurfaceIdentity,
label: String
) async throws {
while let event = try await iterator.next() {
if case .redrawRequested(let candidate) = event,
candidate == surface
{
return
}
}
throw ManagedSurfaceSmokeError.eventStreamEnded(label)
}

private func requireRedrawPresented(
_ outcome: SoftwarePresentationOutcome,
label: String
) throws {
guard outcome == .presented else {
throw ManagedSurfaceSmokeError.unexpectedPresentationOutcome(label, outcome)
}
}
}

nonisolated func drawManagedSurfaceFrame(
_ frame: borrowing SoftwareFrame,
color: UInt32
) {
frame.withXRGB8888Rows { row, pixels in
for index in 0..<pixels.count {
let variation = UInt32((row + index) & 0x1F)
unsafe pixels[unchecked: index] = color ^ variation
}
}
}
Loading
Loading