Skip to content

fix(rotation): portrait/landscape theme rendering, save, and CLI bugs on non-square rotated displays#146

Open
Mr-Renegade wants to merge 3 commits into
Lexonight1:mainfrom
Mr-Renegade:main
Open

fix(rotation): portrait/landscape theme rendering, save, and CLI bugs on non-square rotated displays#146
Mr-Renegade wants to merge 3 commits into
Lexonight1:mainfrom
Mr-Renegade:main

Conversation

@Mr-Renegade
Copy link
Copy Markdown

Device

Trofeo Vision 9.16 LCD (0416:5408) — likely affects all non-square displays in 90°/270° rotation.

Version: v9.6.1


Bugs Fixed

1. Themes always save to landscape directory regardless of rotation

DisplayService.save_theme() passed self.lcd_size (native hardware dims, e.g. 1920×462) to ThemePersistence.save(). On a rotated display the canvas is 462×1920, so saved themes landed in theme1920462/ instead of theme4621920/. Selecting that theme back loaded the landscape version and squished it.

Fix: Pass self.canvas_size instead.


2. All GUI theme renders sent to device without encode rotation (squished)

LCDDevice.send() and send_frame() used self.lcd_size and passed encode_angle=0 (default). A portrait canvas image (462×1920) was resized to native (1920×462) without rotation — squished on screen.

Same bug in send_color(), send_image(), and reset().

Fix: Use self.canvas_size and pass encode_angle=self._display_svc._encode_angle().


3. refresh_dirs() doesn't update the theme service

LCDDevice.refresh_dirs() called DisplayService.refresh_dirs() but never propagated the new dirs to _theme_svc. After a rotation change, _theme_svc still held the old (landscape) dir references so theme lookups returned landscape themes.

Fix: After refresh_dirs(), call _theme_svc.set_directories() and load_local_themes() with canvas_size.


4. refresh_dirs() called after theme reload in set_rotation

_reload_theme_for_rotation() ran before refresh_dirs(), so it searched the old directories and fell back silently.

Fix: Call refresh_dirs() before the reload logic.


5. lcd_theme_workflow used lcd_size instead of canvas_size

load_by_name(), mask loading, and the saved-theme restore path all passed lcd_size to theme loading functions. Also user_theme_dir was not searched on rotation reload — custom themes were never found.

Fix: Use canvas_size throughout; add user_theme_dir to the search path.


6. CLI commands fail with "LCD 0 not found" on LY devices

set_rotation, send_color, send_image, set_brightness, set_split_mode were missing _connect_or_fail(). On LY devices (0416:5408) the first auto-discover during trcc() boot silently fails; a second discover() call succeeds. Without _connect_or_fail() forcing that second attempt, every CLI command returned LCD 0 not found.

Fix: Add _connect_or_fail() to these commands.


7. CLI commands ignore saved rotation

initialize_pipeline() did not call restore_device_settings(), so saved rotation/brightness were never applied in the CLI path. encode_angle computed as 0° regardless of saved rotation.

Fix: Call restore_device_settings() from initialize_pipeline() after device init.


8. Per-rotation theme memory

When switching rotation, the app tried to find the current theme name in the new orientation's directory. If not found it silently failed and the old image was squished. There was no memory of which theme was last used at each rotation.

Fix: Save rotation_themes: {degrees: {theme_name, theme_type}} to device config on every theme select. On rotation change, restore the last theme used at that rotation. Falls back to first available theme if none saved.


Commits

  • fix(display): save_theme uses canvas_size instead of lcd_size
  • fix(rotation): correct portrait rendering and per-rotation theme memory
  • fix(cli): connect_or_fail and encode_angle for CLI display commands

If this project helps you, consider buying me a beer 🍺 or Ko-fi

MrRenegade and others added 3 commits May 12, 2026 21:48
On non-square displays with rotation (e.g. 1920x462 mounted portrait at
270°), themes were being saved to the landscape directory (theme1920462)
instead of the portrait directory (theme4621920). This caused saved
portrait themes to appear squished when reloaded.

Root cause: save_theme() passed self.lcd_size (native hardware dims) to
ThemePersistence.save() and used lcd_width/lcd_height for
current_theme_path. Both should use canvas_size, which already accounts
for rotation via the is_rotated() swap.

Fixes: portrait theme save on 0416:5408 (Trofeo Vision 9.16 LCD) and
any other non-square display mounted in 90°/270° rotation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes multiple rotation-related bugs for non-square displays (0416:5408
Trofeo Vision 9.16 LCD and similar):

1. lcd.py: send()/send_frame()/send_color()/send_image()/reset() now
   pass encode_angle from _display_svc so portrait images are rotated
   to native orientation before sending to device firmware.

2. lcd.py: restore_device_settings() called from initialize_pipeline()
   so CLI commands restore saved rotation/brightness on connect.

3. lcd.py: refresh_dirs() called before theme reload on rotation change
   so theme service gets portrait dirs before searching for themes.

4. lcd.py: removed _reload_theme_for_rotation() from set_rotation —
   GUI now owns rotation theme restore via per-rotation memory.

5. lcd_theme_workflow.py: user_theme_dir searched first so custom
   themes are found on rotation change. canvas_size used instead of
   lcd_size for mask/theme loading dimensions.

6. lcd_handler.py: per-rotation theme memory — each rotation saves and
   restores its own last-used theme independently. Falls back to first
   available theme when no saved theme exists for a rotation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLI commands rotation/color/send/brightness/split-mode were failing with
'LCD 0 not found' on LY devices because _connect_or_fail() was missing.
send_color/send_image/reset also used lcd_size instead of canvas_size
and omitted encode_angle, causing squished output on rotated displays.
initialize_pipeline now calls restore_device_settings() so CLI commands
pick up the saved rotation without needing the GUI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant