From 818a08824ca25f2cc61d9b2f99bf5c7d9e772328 Mon Sep 17 00:00:00 2001 From: "Robin E. R. Davies" Date: Mon, 14 Jul 2025 18:13:09 -0400 Subject: [PATCH] Android Cilent Layout Issues --- CMakeLists.txt | 2 +- _includes/gallery.html | 2 +- docs/_includes/gallery.html | 2 +- src/main.cpp | 34 +-- todo.txt | 21 +- vite/index.html | 195 ++++++++++-------- vite/public/css/modGui.css | 1 + vite/src/pipedal/AutoZoom.tsx | 8 +- vite/src/pipedal/FilePropertyDialog.tsx | 2 +- vite/src/pipedal/FullScreenIME.tsx | 8 +- vite/src/pipedal/LoadPluginDialog.tsx | 14 +- vite/src/pipedal/MainPage.tsx | 18 +- vite/src/pipedal/MidiBindingView.tsx | 6 +- vite/src/pipedal/PiPedalModel.tsx | 9 + vite/src/pipedal/PluginControlView.tsx | 8 +- .../src/pipedal/ResizeResponsiveComponent.tsx | 12 +- vite/src/pipedal/SnapshotDialog.tsx | 2 +- vite/src/pipedal/SnapshotPanel.tsx | 8 +- vite/src/pipedal/SnapshotPropertiesDialog.tsx | 2 +- vite/src/pipedal/TextFieldEx.tsx | 2 +- vite/src/pipedal/UseWindowSize.tsx | 4 +- vite/src/pipedal/Utility.tsx | 6 +- vite/src/pipedal/VirtualKeyboardHandler.tsx | 2 +- vite/src/pipedal/WindowScale.tsx | 2 +- 24 files changed, 195 insertions(+), 175 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf21e66..efea7f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "IoT guitar effect pedal for Raspberry Pi" set(CPACK_DEBIAN_PACKAGE_SECTION sound) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) -set(CPACK_DEBIAN_PACKAGE_DEPENDS "lv2-dev, authbind, curl, gpg, alsa-base| pipewire, alsa-utils" ) +set(CPACK_DEBIAN_PACKAGE_DEPENDS "lv2-dev, ffmpeg, authbind, curl, gpg, alsa-base| pipewire, alsa-utils" ) set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${DEBIAN_ARCHITECTURE}) set(CPACK_PACKAGING_INSTALL_PREFIX /usr) set(CPACK_PROJECT_NAME ${PROJECT_NAME}) diff --git a/_includes/gallery.html b/_includes/gallery.html index 35a8db4..978ac2e 100644 --- a/_includes/gallery.html +++ b/_includes/gallery.html @@ -29,7 +29,7 @@ let galleryFrame = 0; let calculateWidth = function () { - width = Math.min(maxWidth, window.innerWidth * 0.8); + width = Math.min(maxWidth, document.documentElement.clientWidth * 0.8); height = width * aspectY / aspectX; frameWidth = width + borderWidth * 2; frameHeight = height + borderWidth * 2; diff --git a/docs/_includes/gallery.html b/docs/_includes/gallery.html index e224e83..d0dfefb 100644 --- a/docs/_includes/gallery.html +++ b/docs/_includes/gallery.html @@ -34,7 +34,7 @@ let galleryFrame = 0; let calculateWidth = function () { - width = Math.min(maxWidth, window.innerWidth * 0.8); + width = Math.min(maxWidth, document.documentElement.clientWidth * 0.8); height = width * aspectY / aspectX; frameWidth = width + borderWidth * 2; frameHeight = height + borderWidth * 2; diff --git a/src/main.cpp b/src/main.cpp index 12ead14..0665dcc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,27 +82,27 @@ static bool isJackServiceRunning() return std::filesystem::exists(path); } -#if ENABLE_BACKTRACE -void segvHandler(int sig) -{ - void *array[10]; +#if 0 && ENABLE_BACKTRACE +// void segvHandler(int sig) +// { +// void *array[10]; - // Get void*'s for all entries on the stack - size_t size; - size = backtrace(array, 10); +// // Get void*'s for all entries on the stack +// size_t size; +// size = backtrace(array, 10); - // Print out all the frames to stderr - const char *message = "Error: SEGV signal received.\n"; - auto _ = write(STDERR_FILENO, message, strlen(message)); +// // Print out all the frames to stderr +// const char *message = "Error: SEGV signal received.\n"; +// auto _ = write(STDERR_FILENO, message, strlen(message)); - backtrace_symbols_fd(array + 2, size - 2, STDERR_FILENO); - _exit(EXIT_FAILURE); -} +// backtrace_symbols_fd(array + 2, size - 2, STDERR_FILENO); +// _exit(EXIT_FAILURE); +// } -static void EnableBacktrace() -{ - signal(SIGSEGV, segvHandler); -} +// static void EnableBacktrace() +// { +// signal(SIGSEGV, segvHandler); +// } #endif static bool TryGetLogLevel(const std::string &strLogLevel, LogLevel *result) diff --git a/todo.txt b/todo.txt index c217866..2e6706f 100644 --- a/todo.txt +++ b/todo.txt @@ -1,22 +1,10 @@ +Persist and reconnect IP addresses in client. +Zeroconv crash assert. /var/pipedal/audio_uploads/ReverbImpulseFiles/ -Magic zoom. - -request cacheing not working. +Investigate if ((keyCode == KeyEvent.KEYCODE_BACK)) MOD ir uses some scheme to limit the minimum buffer size, which is not implemented in Pipedal. -MOD ir layout issues. - -MOD gui control should disable, not disappear. - -MOD ir font (cooper-hewitt) - -detect self-set control values to prevent weird jitter in mod ui levels. - -ZAMEq2 Low control not working. - - -Modgui view should be persistent/per-plugin Vu Meters, move rendering to background images, in order to reduce layout overhead. @@ -26,9 +14,6 @@ Remove FullScreenIME in PluginControlView.tsx Exactly one underrun per seek in Toob Player -Test autohotspot detection. - -Ellipsis on plugin Title check filetime conversion in gcc 12.2! (missing c++ 20 time conversion functions) AudioFiles.cpp fileTimeToInt64 diff --git a/vite/index.html b/vite/index.html index 68c9bd8..66a5daf 100644 --- a/vite/index.html +++ b/vite/index.html @@ -1,112 +1,133 @@ - + + - + - + - + PiPedal - - + + +
- + + + + diff --git a/vite/public/css/modGui.css b/vite/public/css/modGui.css index 44587c1..984aa13 100644 --- a/vite/public/css/modGui.css +++ b/vite/public/css/modGui.css @@ -40,6 +40,7 @@ } .mod-pedal { + touch-action: none; } .mod-pedal .mod-light { diff --git a/vite/src/pipedal/AutoZoom.tsx b/vite/src/pipedal/AutoZoom.tsx index 4f0589a..2914403 100644 --- a/vite/src/pipedal/AutoZoom.tsx +++ b/vite/src/pipedal/AutoZoom.tsx @@ -113,6 +113,7 @@ const AutoZoom = withStyles( buttonPadding: number ): Rect { + console.log("Zoom: " + clientRect.toString() + " content: " + contentWidth + "x" + contentHeight + " buttonPadding: " + buttonPadding); let rightButtonZoom = Math.min((clientRect.width - buttonPadding) / contentWidth, clientRect.height / contentHeight); let topButtonZoom = Math.min((clientRect.width - buttonPadding) / contentWidth, (clientRect.height - buttonPadding) / contentHeight); @@ -302,12 +303,13 @@ const AutoZoom = withStyles( render() { const classes = withStyles.getClasses(this.props); void classes; // suppress unused variable warning + const landscape = this.state.screenWidth > this.state.screenHeight; return (
{ this.setNormalRef(ref); }}>
{!this.props.showZoomed && this.props.children}
@@ -349,7 +351,9 @@ const AutoZoom = withStyles( { diff --git a/vite/src/pipedal/FilePropertyDialog.tsx b/vite/src/pipedal/FilePropertyDialog.tsx index b927a33..bca518f 100644 --- a/vite/src/pipedal/FilePropertyDialog.tsx +++ b/vite/src/pipedal/FilePropertyDialog.tsx @@ -246,7 +246,7 @@ export default withStyles( this.requestScroll = true; } getFullScreen() { - return window.innerWidth < 450 || window.innerHeight < 450; + return document.documentElement.clientWidth < 450 || document.documentElement.clientHeight < 450; } hProgressTimeout: number | null = null; diff --git a/vite/src/pipedal/FullScreenIME.tsx b/vite/src/pipedal/FullScreenIME.tsx index a9b3930..c762cea 100644 --- a/vite/src/pipedal/FullScreenIME.tsx +++ b/vite/src/pipedal/FullScreenIME.tsx @@ -99,14 +99,14 @@ const FullScreenIME = // because we can't determine the initial window heigth anymore. if (this.currentWidth === undefined) { - this.currentWidth = window.innerWidth; + this.currentWidth = document.documentElement.clientWidth; } - if (this.currentWidth !== window.innerWidth) + if (this.currentWidth !== document.documentElement.clientWidth) { this.validateInput(true); } // eslint-disable-next-line no-restricted-globals - if (window.innerHeight >= this.props.initialHeight) { + if (document.documentElement.clientHeight >= this.props.initialHeight) { this.validateInput(true); } } @@ -194,7 +194,7 @@ const FullScreenIME = this.currentWidth = undefined; return (
); } - this.currentWidth = window.innerWidth; + this.currentWidth = document.documentElement.clientWidth; this.uiControl = control; diff --git a/vite/src/pipedal/LoadPluginDialog.tsx b/vite/src/pipedal/LoadPluginDialog.tsx index d3aed6f..6661157 100644 --- a/vite/src/pipedal/LoadPluginDialog.tsx +++ b/vite/src/pipedal/LoadPluginDialog.tsx @@ -209,10 +209,10 @@ export const LoadPluginDialog = search_string: "", search_collapsed: true, filterType: filterType_, - client_width: window.innerWidth, - client_height: window.innerHeight, - grid_cell_width: this.getCellWidth(window.innerWidth), - grid_cell_columns: this.getCellColumns(window.innerWidth), + client_width: document.documentElement.clientWidth, + client_height: document.documentElement.clientHeight, + grid_cell_width: this.getCellWidth(document.documentElement.clientWidth), + grid_cell_columns: this.getCellColumns(document.documentElement.clientWidth), minimumItemWidth: props.minimumItemWidth ? props.minimumItemWidth : 220, favoritesList: this.model.favorites.get(), uiPlugins: this.model.ui_plugins.get() @@ -276,9 +276,9 @@ export const LoadPluginDialog = updateWindowSize() { this.setState({ - client_width: window.innerWidth, - client_height: window.innerHeight, - grid_cell_width: this.getCellWidth(window.innerWidth), + client_width: document.documentElement.clientWidth, + client_height: document.documentElement.clientHeight, + grid_cell_width: this.getCellWidth(document.documentElement.clientWidth), grid_cell_columns: this.getCellColumns(window.innerWidth) }); } diff --git a/vite/src/pipedal/MainPage.tsx b/vite/src/pipedal/MainPage.tsx index 654006f..8d3f3e9 100644 --- a/vite/src/pipedal/MainPage.tsx +++ b/vite/src/pipedal/MainPage.tsx @@ -82,7 +82,7 @@ const styles = ({ palette }: Theme) => { }), pedalboardScroll: css({ position: "relative", width: "100%", - flex: "0 0 auto", overflow: "auto", maxHeight: 220 + flex: "0 0 auto", overflow: "auto", maxHeight: 220, }), pedalboardScrollSmall: css({ position: "relative", width: "100%", @@ -100,7 +100,7 @@ const styles = ({ palette }: Theme) => { flex: "0 0 64px", width: "100%", paddingLeft: 24, paddingRight: 16, paddingBottom: 16 }), controlContent: css({ - flex: "1 1 auto", width: "100%", overflowY: "hidden", minHeight: 300 + flex: "1 1 auto", width: "100%", overflowY: "hidden", minHeight: 185 }), controlContentSmall: css({ flex: "0 0 162px", width: "100%", height: 162, overflowY: "hidden", @@ -145,7 +145,7 @@ export const MainPage = model: PiPedalModel; getSplitToolbar() { - return this.windowSize.width < SPLIT_CONTROLBAR_THRESHHOLD; + return this.windowSize.width < SPLIT_CONTROLBAR_THRESHHOLD && this.windowSize.height >= HORIZONTAL_CONTROL_SCROLL_HEIGHT_BREAK; } getDisplayAuthor() { if (this.getSplitToolbar()) { @@ -621,12 +621,12 @@ export const MainPage =
- +
diff --git a/vite/src/pipedal/MidiBindingView.tsx b/vite/src/pipedal/MidiBindingView.tsx index ad4e554..861cfb2 100644 --- a/vite/src/pipedal/MidiBindingView.tsx +++ b/vite/src/pipedal/MidiBindingView.tsx @@ -58,13 +58,13 @@ export enum MidiControlType { } export function getMidiControlType(uiPlugin: UiPlugin | undefined, symbol: string): MidiControlType { + if (symbol === "__bypass") { + return MidiControlType.Toggle; + } if (!uiPlugin) return MidiControlType.None; let port = uiPlugin.getControl(symbol); if (!port) return MidiControlType.None; - if (symbol === "__bypass") { - return MidiControlType.Toggle; - } if (!port) return MidiControlType.None; diff --git a/vite/src/pipedal/PiPedalModel.tsx b/vite/src/pipedal/PiPedalModel.tsx index 0fda9f3..56eafa0 100644 --- a/vite/src/pipedal/PiPedalModel.tsx +++ b/vite/src/pipedal/PiPedalModel.tsx @@ -609,6 +609,13 @@ export class PiPedalModel //implements PiPedalModel let message = header.message; if (message === "onControlChanged") { let controlChangedBody = body as ControlChangedBody; + if (body.clientId !== this.clientId) { + this.lastControlMessageWasSentbyMe = false; + } + if (this.lastControlMessageWasSentbyMe) { + return; // shortcut! + } + this._setPedalboardControlValue( controlChangedBody.instanceId, controlChangedBody.symbol, @@ -1529,6 +1536,7 @@ export class PiPedalModel //implements PiPedalModel } } + private lastControlMessageWasSentbyMe = false; private _setPedalboardControlValue(instanceId: number, key: string, value: number, notifyServer: boolean): void { let pedalboard = this.pedalboard.get(); @@ -1547,6 +1555,7 @@ export class PiPedalModel //implements PiPedalModel if (changed) { if (notifyServer) { + this.lastControlMessageWasSentbyMe = true; this._setServerControl("setControl", instanceId, key, value); } this.setModelPedalboard(newPedalboard); diff --git a/vite/src/pipedal/PluginControlView.tsx b/vite/src/pipedal/PluginControlView.tsx index 976b9cd..2fc820f 100644 --- a/vite/src/pipedal/PluginControlView.tsx +++ b/vite/src/pipedal/PluginControlView.tsx @@ -146,9 +146,9 @@ const styles = (theme: Theme) => createStyles({ flexDirection: "row", flexWrap: "nowrap", paddingTop: "0px", - paddingBottom: "0px", + paddingBottom: "96px", overflowX: "hidden", - overflowY: "auto" + overflowY: "auto", }), vuMeterL: css({ position: "absolute", @@ -175,7 +175,7 @@ const styles = (theme: Theme) => createStyles({ right: 0, top: 0, paddingRight: 6, paddingLeft: 12, - paddingBottom: 12, // cover bottom line of a portgroup in landscape. + paddingBottom: 13, // cover bottom line of a portgroup in landscape. background: theme.mainBackground, zIndex: 3 @@ -448,7 +448,7 @@ const PluginControlView = imeUiControl: uiControl, imeValue: value, imeCaption: uiControl.name, - imeInitialHeight: window.innerHeight + imeInitialHeight: document.documentElement.clientHeight }); } diff --git a/vite/src/pipedal/ResizeResponsiveComponent.tsx b/vite/src/pipedal/ResizeResponsiveComponent.tsx index a46f6e8..726b352 100644 --- a/vite/src/pipedal/ResizeResponsiveComponent.tsx +++ b/vite/src/pipedal/ResizeResponsiveComponent.tsx @@ -24,8 +24,8 @@ class ResizeResponsiveComponent extends React.Component constructor(props: PROPS) { super(props); this.handleWindowResize = this.handleWindowResize.bind(this); - this.windowSize.width = window.innerWidth; - this.windowSize.height = window.innerHeight; + this.windowSize.width = document.documentElement.clientWidth; + this.windowSize.height = document.documentElement.clientHeight; } windowSize: {width: number,height:number} = {width: 1280, height: 1024}; @@ -34,8 +34,8 @@ class ResizeResponsiveComponent extends React.Component } handleWindowResize() { - let width_ = window.innerWidth; - let height_ = window.innerHeight; + let width_ = document.documentElement.clientWidth; + let height_ = document.documentElement.clientHeight; if (width_ !== this.windowSize.width || height_ !== this.windowSize.height) { this.windowSize = {width: width_, height: height_}; @@ -49,8 +49,8 @@ class ResizeResponsiveComponent extends React.Component componentDidMount() { window.addEventListener('resize', this.handleWindowResize); - let width_ = window.innerWidth; - let height_ = window.innerHeight; + let width_ = document.documentElement.clientWidth; + let height_ = document.documentElement.clientHeight; this.windowSize = {width: width_, height: height_}; this.onWindowSizeChanged(this.windowSize.width,this.windowSize.height); } diff --git a/vite/src/pipedal/SnapshotDialog.tsx b/vite/src/pipedal/SnapshotDialog.tsx index 765de56..1bea229 100644 --- a/vite/src/pipedal/SnapshotDialog.tsx +++ b/vite/src/pipedal/SnapshotDialog.tsx @@ -89,7 +89,7 @@ export default class SnapshotDialog extends ResizeResponsiveComponent 700 && window.innerWidth > 1000; + return document.documentElement.clientHeight > 700 && document.documentElement.clientWidth > 1000; } onSaveSnapshot(index: number) { let snapshot = this.state.snapshots[index]; diff --git a/vite/src/pipedal/SnapshotPropertiesDialog.tsx b/vite/src/pipedal/SnapshotPropertiesDialog.tsx index 9296218..c69128a 100644 --- a/vite/src/pipedal/SnapshotPropertiesDialog.tsx +++ b/vite/src/pipedal/SnapshotPropertiesDialog.tsx @@ -64,7 +64,7 @@ export default class SnapshotPropertiesDialog extends ResizeResponsiveComponent< this.state = this.stateFromProps(); } getCompactVertical() { - return window.innerHeight < 450; + return document.documentElement.clientHeight < 450; } stateFromProps() { let color = this.props.color; diff --git a/vite/src/pipedal/TextFieldEx.tsx b/vite/src/pipedal/TextFieldEx.tsx index 9facc9d..e109e59 100644 --- a/vite/src/pipedal/TextFieldEx.tsx +++ b/vite/src/pipedal/TextFieldEx.tsx @@ -52,7 +52,7 @@ const TextFieldEx = withStyles(styles, { withTheme: true })( } private getUseImeMask() { - return this.state.androidHosted && window.innerHeight < 4500; + return this.state.androidHosted && document.documentElement.clientHeight < 4500; } private originalInputHref: HTMLInputElement | undefined = undefined; diff --git a/vite/src/pipedal/UseWindowSize.tsx b/vite/src/pipedal/UseWindowSize.tsx index e14c206..7fa73f3 100644 --- a/vite/src/pipedal/UseWindowSize.tsx +++ b/vite/src/pipedal/UseWindowSize.tsx @@ -25,8 +25,8 @@ import { useState, useEffect } from 'react'; const getSize = () => { return { - width: window.innerWidth, - height: window.innerHeight, + width: document.documentElement.clientWidth, + height: document.documentElement.clientHeight, }; }; diff --git a/vite/src/pipedal/Utility.tsx b/vite/src/pipedal/Utility.tsx index 50a8d37..47919e0 100644 --- a/vite/src/pipedal/Utility.tsx +++ b/vite/src/pipedal/Utility.tsx @@ -39,13 +39,13 @@ export interface ControlEntry { const Utility = class { static isLandscape(): boolean { - return window.innerWidth > window.innerHeight; + return document.documentElement.clientWidth > document.documentElement.clientHeight; } static needsZoomedControls(): boolean { if (!this.isLandscape()) return false; - if (window.innerHeight > 500) return false; - if (window.innerHeight > 300) return true; + if (document.documentElement.clientHeight > 500) return false; + if (document.documentElement.clientHeight > 300) return true; return (('ontouchstart' in window) && ((navigator.maxTouchPoints??0) > 0) ); } diff --git a/vite/src/pipedal/VirtualKeyboardHandler.tsx b/vite/src/pipedal/VirtualKeyboardHandler.tsx index cb8689f..0d169ab 100644 --- a/vite/src/pipedal/VirtualKeyboardHandler.tsx +++ b/vite/src/pipedal/VirtualKeyboardHandler.tsx @@ -51,7 +51,7 @@ export default class VirtualKeyboardHandler enabled = false; } this.enabled = enabled; - this.originalPosition = new Rectangle(0,0, window.innerWidth,window.innerHeight) + this.originalPosition = new Rectangle(0,0, document.documentElement.clientWidth,document.documentElement.clientHeight) } private handleVisualViewportResize(event: Event): void { const viewport = event.target as VisualViewport; diff --git a/vite/src/pipedal/WindowScale.tsx b/vite/src/pipedal/WindowScale.tsx index aac1d4f..dd708da 100644 --- a/vite/src/pipedal/WindowScale.tsx +++ b/vite/src/pipedal/WindowScale.tsx @@ -15,7 +15,7 @@ export function getValidWindowScales(): number[] return [1.0]; } let result: number[] = []; - let minDimension = Math.min(window.innerHeight,window.innerWidth); + let minDimension = Math.min(document.documentElement.clientHeight,document.documentElement.clientWidth); for (let validScale of validScales) {