Skip to content

Release 0.3.5 candidate - #197

Draft
whoisaldo wants to merge 226 commits into
mainfrom
release/0.3.5-candidate
Draft

whoisaldo wants to merge 226 commits into
mainfrom
release/0.3.5-candidate

Conversation

@whoisaldo

Copy link
Copy Markdown
Member

Draft that runs the full CI matrix on the combined 0.3.5 candidate. CI only runs on pull requests, so this checks the merged PRs together, not just one at a time. It stays a draft until 0.3.5 is ready for a stable release.

Merged into the candidate so far:

whoisaldo and others added 30 commits November 3, 2026 17:36
libx264 refuses an odd width or height (4:2:0 needs even dimensions), so
a 1680x945 screen with no usable hardware encoder never streamed: the
encoder failed to open on every restart until the pipeline gave up.

The encoder now opens at the even size below the capture and drops the
odd last column or row, on every input path (swscale to YUV420P/NV12,
Accelerate on macOS, the BGRA copy NVENC reads). The crop reads the
capture's top-left region in place, so no pixel is resampled. The size
check compares encoded sizes, so an odd capture does not reopen the
encoder every frame. The stream config, GUI and stats report the encoded
size; one info line per open names both sizes.

Input still maps onto the whole capture: each pixel of the cropped
picture lands on itself and the picture's far edge reaches the row or
column left out.
Stream screens with an odd width or height
On a hybrid laptop, Windows can put the desktop on the virtual display
alone when it turns on. The host only logged that, waited 30 s for an
attach that could not happen, then turned the display off, after which
Windows reported no screen at all and refused every layout until a
restart.

The display guard now acts while the virtual display is still on. A
turn on that leaves it alone, where the PC had a real screen before,
switches Windows to Extend, else re-applies the saved layout, else
PC screen only. A turn off that finds it alone puts a real screen back
first, and does not run if nothing does. A start whose display was left
alone falls back to the mirror at once with second_screen_fallback
vdd_only, remembered like an attach timeout.
…lock

An iPad whose HELLO never reaches the PC says "Your PC didn't answer"
while the PC says it is ready, and neither side could say why.

- Setup now deletes every inbound rule for EternalMonitor-host.exe
  before it adds its Allow rule. Windows adds inbound Block rules for
  an app when its "allow access" prompt is dismissed, and a Block rule
  beats an Allow rule, so running Setup again, the fix the iPad
  suggests, left the block in place.
- The host reads the firewall policy at startup and every minute and
  logs the profiles in use, the Allow and Block rules for its own exe
  and a verdict. The Stream page warns while a Block rule or "Blocks
  all incoming connections" keeps iPads out.
- The network line names the adapter kinds that hold a home network
  address, which tells a PC on a cable from one on Wi-Fi.
Review fixes for the Windows Firewall check:

- A Block rule counts only when it reaches the stream's port. One
  scoped to remote or local addresses, remote ports, interfaces or a
  service is logged as scoped_block_rules and never shown.
- Each profile in use keeps its own verdict. The Stream page warns
  only when every profile blocks and the PC has a home network
  address; a block on one of two networks is logged as
  partly_blocked.
- The warning stays hidden while any iPad is connected, over Wi-Fi
  or the cable.
- A failed read clears the last reading, so an old block can't stay
  on screen.
- The line's keys are diagnostic keys: a PC or user named like a
  token no longer changes it in uploads.
…t read

Review fixes for the Windows Firewall check:

- A Block rule with no program blocks every app, ours included. It is
  now judged like ours when it covers the stream's port, logged as
  all_programs_block_rules, and the Stream page points to Windows
  Security instead of Setup, which deletes only this exe's rules.
- A rule field that could not be read is unknown, not "any". A rule
  with an unknown scope or program is logged as scoped and never
  makes a block certain. Rules are read through a small trait, so
  tests can fail each getter.
Review fixes for the Windows Firewall check:

- Rules are also read through INetFwRule3: an app package, a user
  owning the process, authorized local or remote users or machines,
  or IPsec SecureFlags limit whose traffic a rule is for. Any of them,
  set or unread, makes a rule scoped, so it never makes a block
  certain.
- The Stream page warns only for this exe's own unscoped Block rule,
  which Setup removes, or "Blocks all incoming connections" on every
  profile in use. A Block rule for every program is logged
  (blocked_all_programs) and never shown.
- An enabled Allow rule for this exe or every program that asks for
  IPsec may override Block rules for authenticated traffic. Any such
  rule makes a block uncertain: verdict=uncertain, bypass_rules=N,
  no warning.
Say when Windows Firewall keeps iPads out, and let Setup remove the block
FFmpeg 7.1 only uses swscale's threads through sws_scale_frame, so the
encoder's scaler is now built with a thread count (half the logical
processors, at most four) and converts capture's rows where they lie
through sws_scale_frame, with a buffer that never frees them. YUV420
input, which AMF, Quick Sync, x264 and PCs that kept YUV420 from 0.3.4
use, took about 14 ms per 2732x2048 frame on one thread.

The swscale line in the log now says how many threads it uses.
On an AMD hybrid laptop, the virtual display's arrival takes the built-in
panel away below the layout: Windows lists the panel's target as
unavailable, refuses every layout that names it, and only a restart gives
it back. The guard now tells that case apart on a PC with more than one
graphics card (the virtual display on, the panel off, no built-in target
offered) and makes no SetDisplayConfig call. Every turn off stays held, at
start-up too, so the desktop stays on the display the iPad shows; only
Windows ending the session lets the turn off run, so the restart starts
without the display.

Second screen falls back at once with second_screen_fallback="panel_lost"
and leaves the display on. The failure is saved until Second screen is
chosen again: no wait, update, or blocked mirror tries it by itself. It is
saved as an attach_timeout with panel_lost set, which older versions read
as a timeout. The Stream page says to save work on the iPad and restart.
When a saved PC's HELLO2s go unanswered, look it up by its Bonjour name.
If exactly one PC claims that name at another address, connect there and
send the saved pairing. The PC must give back the same name and token,
otherwise the iPad leaves it and keeps its pairing. Addresses the user
typed and host names are never looked up. A home network entry gives way
to the new address; VPN and Tailscale entries stay.

Recent entries now keep the PC's name and whether the address was typed.
The abandoned attempt's summary reads outcome=no_reply end=superseded.
If the new address does not answer either, the card says where the iPad
found the PC.

scripts/e2e_moved_pc.sh streams from 127.0.0.1, moves the host, and
expects the app to stream again by itself.
…rt loop

Quitting, Stop and the storm brake ended the PC's stream without a word to
the iPad. A quit or a self-restart showed up on the iPad as a lost signal or
an unplugged cable. After Stop or Failed the session even stayed open with
nothing ticking it: no heartbeats, no liveness expiry, and new HELLOs went
unanswered until the next Start or quit.

- Session::shut_down now ends the session with a goodbye that the transport
  sends on its way out, over UDP or the USB tunnel. Quit and Stop say
  user_disconnect, so the iPad shows "Your PC ended the session" and stays
  away. A restart or update handoff, and the storm brake, say error, so the
  iPad reconnects at once.
- The supervisor ends the session when it stops for a manual Start (Stopped,
  Failed). A backoff or a held port keeps it, as before.
- A goodbye left while no transport ran is dropped when the next one starts.
- The transport loop marks a heartbeat with the step it is in. The
  supervisor's thread logs one line (stall="transport_loop" phase=...) when
  the mark is 2 s old, and one when the loop moves again. A gap in the
  supervisor's own checks (PC asleep) is not counted.
…, Apple Devices is missing or the PC is old

- No complete frame 2 s after video began: the reassembler names the
  missing fragments of the latest incomplete frames and the largest
  fragment received, the app logs it and asks the PC for a fresh
  keyframe with reason Startup, and again every 2 s while video still
  arrives. Startup passes the 500 ms request spacing, which the dropped
  frames' own requests keep busy. The PC's packet size has no control
  message, so the iPad can't ask for smaller datagrams.
- A Wi-Fi link failure with no network ends the attempt as noNetwork,
  summarized as failure=no_network instead of other. The card says
  "Wi-Fi is off".
- A PC whose HELLO_ACK lacks the USB capability can't reach Apple's
  USB service: the USB card says Apple Devices isn't running there.
- The update check keeps the manifest's Windows version. A PC found by
  Bonjour with an older version gets "Update EternalMonitor on your PC"
  under its row.
Turning pairing off is the user's setting, so the startup line is info, not a warning. The host re-advertises mDNS every minute and logged each one; it now logs a re-advertisement when its addresses change and otherwise once an hour, with how many went unlogged.
An iPad that says it draws the pointer (HELLO2 feature bit 5) gets the
pointer image and its position as control messages from a host that
says it sends them (host capability bit 6). The host then leaves the
pointer out of the video, and a pointer-only update needs no frame, so
pointer motion no longer waits for the encoder.

- POINTER_SHAPE (0x1A) carries the image in chunks: premultiplied BGRA
  and, when a pixel inverts the picture under it, an invert mask.
  Monochrome, color and masked-color Windows pointers convert to it.
- POINTER_STATE (0x1B) carries the position and visibility, at most one
  per frame budget, the newest, and once more 100 ms after the last.
- Receiver reports append the image id the iPad holds, so a lost chunk
  is sent again; the image also goes with every session start and IDR.
- The iPad draws the image over the video in the Metal pass, through the
  same content rect the touch relay uses, with a second pass that
  inverts the picture where the mask says.
- iPads and hosts without the bits behave as before.

Fixes #183
…ice is lost

egui-wgpu 0.36 panicked on the frame after a device loss ("Failed to create
staging buffer for index data"), which ended the app. The vendored copy now
skips that frame, drops the lost device and builds a new one, and the window
reloads its logo on the new device. A replacement device leaves the launch's
crash-avoidance marker alone.
While the lock screen or a permission prompt is up, Windows lets nothing
capture the screen, and the iPad showed a frozen picture without a word
(SecureDesktop: 22 events on 13 installs in a day, 116 resumes on 28).

The heartbeat gets an appended notice byte, sent only while there is a
notice. The PC sets it from the capture block: PC locked for
SecureDesktop, nothing for the rest, and it clears when capture works
again. Control bodies are append-only and both parsers ignore trailing
bytes, so older iPads read the same heartbeat as before, and a plain
heartbeat is byte-identical. New golden vector heartbeat_pc_locked.

The iPad shows a quiet pill over the held picture, "Your PC is locked.
Unlock it to continue.", until a heartbeat says capture works again.
The string is English only, in the catalog and awaiting translation.
… stops in summaries

Review round 1 of the stop goodbyes.

- The transport no longer ends when the encoder closes its video channel.
  The encoder thread drops it before its failure report reaches the
  supervisor, so the transport used to exit before the storm brake queued
  its goodbye; the next transport then dropped it as stale. Now the loop
  stops reading video and runs until `running` goes false.
- After Session::shut_down, HELLOs are refused with Busy until a transport
  resumes. A HELLO before the loop saw `running=false` opened a session
  that nothing served. One place decides it: closed_to_clients.
- Summaries tell stops apart with existing tokens: Stop is end=user, the
  storm brake is end=error with failure=capture_failed, encoder_failed or
  other. A quit stays end=shutdown. SupervisorState::Failed keeps the stage.
- On the iPad, the error goodbye's card is titled "The connection to your PC
  ended", true for a PC that restarts by itself as well as for a fault.
  "Your PC ended the session" stays for Stop and quit. SETUP.md lists both.
- stalled_ms is a diagnostic key. The stall test checks for a free port on
  every address, as the transport binds, and fails fast if the transport
  ends early.
At 4-22% WiFi loss each replacement keyframe arrived incomplete: one
round of requests and repairs leaves some of its 80-300 fragments
missing, and the iPad dropped it at its 25 ms deadline because the small
frames after it, which need it, were already complete. The picture then
froze until the iPad reconnected.

An incomplete keyframe is now held at its deadline while the frames
behind it complete, until it completes, a newer keyframe completes or a
second passes. It asks again every RTT + 5 ms once something has
arrived since its last request. Swift and the Rust mirror change
together, with shared traces.

The WiFi repair simulation at 10% loss each way now completes 397 of 399
keyframes instead of 148 of 390, and no freeze lasts a second (35 did,
up to 3.4 s). A measurement test runs the same loss through the real
encoder and transport.
Log pairing-off at info and collapse unchanged mDNS re-advertisements
Before reconnecting at a new address, the iPad now checks that it is the
same PC. It sends a token-less IDENTIFY with a random nonce, and a PC on
0.3.5 or later answers with HMAC-SHA256 keyed with its pairing token over
the nonce and a fixed context. Only a matching answer lets the normal
HELLO2 go to the new address. A PC that doesn't answer, as before 0.3.5,
means no move. The messages are versioned (0x1A, 0x1B) and older apps and
PCs ignore them.

A saved PC moves only if all of these hold:
- the iPad holds a pairing for it;
- its entry came from Bonjour's list (a new found mark; older, typed and
  scanned entries never move);
- both the old and the new address are home network addresses.

Bonjour services still resolving count when two PCs claim one name.

Try again after a refused move goes back to the saved address. The new
address becomes the target only once the PC is accepted. The old entry
and pairing stay until the new pairing is saved and read back.

The e2e now pairs for real at the Mac's home network address (read at run
time) and moves the PC to another port. Test fixtures use documentation
addresses.
Startup reopened to clients and then, in a second lock, dropped any queued
goodbye as stale. A Stop between the two ended the session and queued a
current goodbye, which startup then dropped: the iPad timed out instead of
showing the card.

Session::transport_resumed now retires a stale goodbye and reopens to
clients in one call, under the lock the transport reads `running` with.
stop_session queues its goodbye and clears `running` under that same lock.
A transport that starts after a stop and sees the stream stopping keeps the
goodbye and sends it on its way out. One that starts first leaves later
goodbyes alone.
… note to its PC, and wait out a keyframe still arriving

Review fixes:

- A waiting connection now carries whether iPadOS called its path
  unsatisfied with no usable network. Only that is the new wifiOff
  problem ("Wi-Fi is off", failure=no_network). Every other path
  failure, no route to the PC or its network included, keeps the card
  and failure=other it had before.
- The Apple Devices note is kept with the PC's target and the time it
  was seen, dropped when an attempt goes to another PC, and stops
  applying after 30 minutes. The card gives it as what happened last
  time and what to try if the cable doesn't connect.
- The no-first-frame watchdog stays quiet while a frame has been
  arriving in order for over 100 ms and still is, as a large keyframe
  does over the cable.
A held keyframe asked for its missing fragments at each hold expiry as
well as on its retry timer, and the hold neither moved the timer nor
waited for traffic. At 1 ms RTT the same fragment went out 1 ms after a
retry, inside the PC's 5 ms resend limit; at 200 ms RTT the holds asked
at 26 and 51 ms, before any repair could return.

A keyframe's hold now only moves its deadline. Every repeated request
goes through one retry: due RTT + 5 ms after the last one, and after
the first only once something arrived since the last request, on a
later tick. Shared traces cover a hold and retry on the same tick,
silence, and 1 ms and 200 ms RTT.
…loop

Windows' input calls wait while it reconfigures displays. On a test PC,
every virtual display change held SendInput for 50-130 ms and pen
injection for about 40 ms, on the transport loop. In the field one such
wait lasted about 53 s: the iPad heard nothing, new HELLOs went
unanswered, and the stopped stream kept its port from the next one.

- The transport queues input; an input thread owns the relay and hands
  it to Windows in order. It also sends pen frames held back for their
  spacing and refreshes a still contact, which the loop did before.
- The queue is bounded. While Windows takes nothing, a pointer or Pencil
  move replaces the move queued just before it. Input that waited over a
  second lands only as a release of what the PC holds, as late input
  from the iPad does. Ends, key releases and resets are never dropped.
- A stopped stream drops its handle at once. The thread then releases
  what the PC holds whenever Windows answers.
- A Windows input call over 250 ms is logged, and so is a backlog once
  it clears.
- input_soak, a fake iPad that streams harmless input while connecting
  and leaving, reproduces the waits on a PC set to Second screen.
Review fix: the 30-minute limit was only checked when SwiftUI redrew
the USB card, so an idle Connect screen kept the hint. The sighting now
carries its expiry, a cancellable task clears that sighting and
publishes the change when it comes, and coming back to the foreground
checks it against the clock again. The clock and the lifetime can be
injected for tests.
whoisaldo and others added 30 commits November 8, 2026 01:58
Show the mirror before the moved-screen test's second screen attaches
A driver update or reset, the case this window recovery is for, can give
an adapter a new LUID. The adapter that drew was then no longer found, so
the choice fell back to any adapter, and adapters left out came back in.
Now an adapter that isn't listed as it was is found as the only listed one
that differs in the LUID alone; two such are no match.

The Vulkan LUID is read only when the device, not just the instance, is
Vulkan 1.1+.
…at/ipad-drawn-cursor

# Conflicts:
#	host/src/transport/mod.rs
Review r6 of #205.

The startup banner's listing was a public function that made its own
token, and the backstop scan matched calls, so a `use … as` alias of it
listed outputs unseen. Visibility can't be narrowed to the banner: it is
in the binary crate, and `pub(in …)` only names ancestor modules. So the
unjudged listing is gone: the banner gets only its display label from
`startup_display_label`, and the native test that prints the outputs
lists them through the judge with its own host state. The debug-build
fake display's outputs now take the same token as the DXGI enumerator,
so the compiler keeps both to `capture::listing`.

The scan matches identifiers outside comments and string literals, so
aliases are seen, and has fixtures for an alias, a grouped import, a
removed name, a comment, a string and a longer name.

`observe_listing` names `OutputInfo` by path: the module imports it only
for Windows, test and debug builds, and a macOS release build failed.
Four more cases now count as Unknown, where the host can't be sure what
the running driver read.

- The driver reads its settings folder from VDDPATH under its registry
  key. Unless that value is unset or names C:\VirtualDisplayDriver
  (ignoring case and a trailing backslash), the file this host writes
  isn't the driver's, and the cursor is Unknown.
- Registry reads count as "no override" only when they find no key or
  no value. Any other error means Unknown.
- The driver's state before an Enable is read as running, off, or
  unreadable. A record is kept only for a driver seen off before the
  Enable and running after it.
- Software now comes only from a file that a driver which reads
  <cursor> started with. An older or unreadable installer version,
  which may not be the running driver's, is Unknown.
- A character or entity reference inside a cursor setting is Unknown:
  XmlLite expands it into the text, while quick-xml reports it apart.
Keep the window and the stream running when the GPU device is lost
… a slow driver

Third review of #206 found five more gaps; this closes them.

- The watcher counted a minimized window as stuck: eframe runs no UI
  pass for one, so the renderer never saw it minimized, and a healthy
  host got the driver notice 4 s after Win+D. The watcher now checks the
  window live (IsIconic, or the move/size and menu loops Windows runs
  while the title bar is held), and counts the 4 s from the latest of its
  start, the last UI pass and the last time it saw the window held.
- Confirming the window could still pass with nothing presented: after a
  failed surface recreation egui-wgpu's paints return early with no
  surface error. The renderer now asks for a screenshot once the window
  has drawn long enough, and confirms only when it arrives; egui-wgpu
  takes one only from a frame it acquired, drew and submitted.
- A driver that always answers after 4 s never opened the window: each
  try was given up on and started again. The list and the probe are now
  one call each, waited for as long as they run; the notice goes up at
  their limit, and a late answer opens the window.
- Tests whose steps answer use 60 s limits, and the watcher's panics
  reach the test.
- The notice box closes on a thread of its own, so the window's thread
  never waits on it.
…x/gpu-detect-timebox-035

# Conflicts:
#	host/src/gui/renderer.rs
Give the startup and quit device read a 2 s limit
When the PC says it sent video and the iPad still has no picture, the
iPad asks for smaller media datagrams (1,200, then 576 bytes, each with a
fresh keyframe). If that doesn't help, it asks the PC to sign its other
home network addresses with the pairing, confirms the same PC at one of
them, and reconnects there. The address that worked is tried first next
time.

The size request is a field appended to KEYFRAME_REQUEST, and the frame
count is appended to HEARTBEAT. Both are gated on FEATURE_MEDIA_SIZE and
HOSTCAP_MEDIA_SIZE, so older PCs and iPads see the same bytes as before.
A PC session that sent video and ended with the iPad's error goodbye
without a counted frame now summarizes as no_video or no_frame instead of
other.
The scan of root devices used to drop a device it couldn't locate, or
whose hardware IDs it couldn't read. A failed read could then leave no
device of the driver, which counted as off. The next successful read
would record a start for a driver that was already running.

- The scan now keeps every present root device as one of:
  - not the driver's: its hardware IDs were read and don't name it, or
    it has none (CR_NO_SUCH_VALUE);
  - the driver's, with its status;
  - unread.
- Any unread device, or a driver device whose status can't be read,
  makes the state unreadable.
- A pure run_from classifies the scan, so a test can inject a failed
  read: the state is unreadable and no record is kept.
A settings file saved in the system's ANSI code page, as Notepad does,
was not UTF-8 or UTF-16, so the host kept the driver's old modes and
skipped the graphics card pin.

The driver reads the file with XmlLite, which takes UTF-8 and UTF-16
but no double-byte code page: declared, it reads nothing; undeclared or
declared UTF-8, it stops at the first non-ASCII byte. The host now
decodes such a file in the code page its declaration names, or in the
system's ANSI code page, and writes it back as UTF-8 with a matching
declaration, which the driver reads to the end. The original is kept
as vdd_settings.xml.bak-<date> first. Bytes that are no character in
that code page leave the file alone, as before.
Recover capture after sleep, lost displays and repeated access loss
- A remembered address gets HELLO2 and the token only after the PC there
  proves it holds the pairing, as a move with the same-PC checks. Without
  the proof, the entry is forgotten and the attempt goes to the address
  tapped. Entries are bound to a digest of the pairing token.
- The other-address step only tries addresses on the iPad's own subnet,
  as a PC that Bonjour moved does.
- Only the first two smaller sizes in a session skip the keyframe rate
  limit; later ones are ordinary keyframe requests.
- The iPad's summary for a move after no picture says no_frame when some
  video arrived, as the PC's does.
…at/ipad-drawn-cursor

# Conflicts:
#	host/src/capture/dxgi.rs
#	host/src/capture/mod.rs
When the pointer's answer changes, the cached frame is rebuilt from the
staging texture. If that copy hit ACCESS_LOST, the error ended the
capture loop. The stage then opened capture afresh after at least
500 ms, which dropped the cached picture and skipped the quick
re-creation of the duplication.

- ACCESS_LOST from the copy now goes to the loop's existing handler,
  as one from ReleaseFrame or the readback does. The cache is kept.
- While a loss is pending, the rebuild waits until the handler has run.
- Any other error, such as DEVICE_REMOVED, still ends the loop, so the
  pipeline re-creates the device.
- The decision is redraw_cached, generic over the error, so a test can
  inject the ACCESS_LOST.
…x/no-video-path-fallback

# Conflicts:
#	ios/EternalMonitor/Network/WireProtocol.swift
- Before the identity check, a remembered address must be on this
  iPad's own subnet, as the other-address step requires; otherwise the
  entry is forgotten and the attempt goes to the address tapped.
- When the attempt at a remembered address fails after its proof (no
  HELLO2 answer, no picture before the timeout, or another PC by name or
  pairing), the entry is forgotten and a new attempt goes to the address
  tapped.
- Try again and a resume go to the address tapped while the remembered
  one is checked.
- A golden vector covers a heartbeat that carries both the no-display
  notice and the frame count.
…x/gpu-detect-timebox-035

# Conflicts:
#	host/src/gui/mod.rs
#	host/src/main.rs
#	host/src/stall.rs
A settings file read from a code page is now written back as UTF-8 even
when its graphics card stays, so the driver reads all of it.

UTF-8 with stray bytes is no longer read in the system's code page when
it starts with a byte order mark, or, in a single-byte code page, when
it still holds UTF-8 beyond ASCII; its UTF-8 text would be garbled.

A second conversion the same day keeps its original as
vdd_settings.xml.bak-<date>-<n>. Each conversion is logged once.

Tests cover the system code page through apply_pin and write_with_pin.
Fourth review of #206 found three more gaps; this closes them.

- A window whose paints return without a surface keeps running UI
  passes, so the watcher's 4 s without a pass never came, and its
  screenshots were asked for again and again with no notice. The watcher
  now also raises the notice when the window has run UI passes for 12 s
  without being confirmed drawing (a working one is at about 3.5 s). Both
  bounds count from the latest of the start and the last time the window
  was held, so a minimized or dragged window suspends them.
- Any screenshot marked as the proof was accepted, also a late one from
  before a surface error or a new device. Each ask now carries its span
  (a new one after each surface error, skipped frame or device) and a
  request id, and only an answer to the current span's asks confirms.
- The watcher's decisions are a step function the tests call with each
  state in turn, instead of a thread they hoped had looked.
The mixed UTF-8 cases are refused only in a single-byte system code
page, so the file-level cases now run only there and both byte orders
are tested in code page 1252 directly. The backup test passes its date
instead of reading the clock.
Draw the pointer on the iPad, apart from the video
…x/no-video-path-fallback

# Conflicts:
#	ios/EternalMonitor/App/ConnectionManager.swift
#	ios/EternalMonitor/Network/WireProtocol.swift
#	ios/EternalMonitorTests/WireProtocolGoldenTests.swift
#	proto/src/v2/control.rs
#	proto/tests/golden.rs
Use smaller packets or the PC's other address when no video arrives
Read vdd_settings.xml saved in a Windows code page
Keep a stuck graphics driver from holding the window at start

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

0.3.5 After 0.3.4

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants