OpenRGB dedup fix, device card URL badge overflow fix
- Replace threshold-based dedup with exact equality check in OpenRGB client; threshold dedup caused animation stutter at low software brightness - Add brightness_control capability to OpenRGB provider (software simulated) - Fix device card URL/COM badge overlapping close button: badge stays inside card-title flex container, both name and badge truncate with ellipsis Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,7 +96,7 @@ class OpenRGBLEDClient(LEDClient):
|
|||||||
self._send_pending: Optional[Tuple[np.ndarray, int]] = None # (pixels, brightness)
|
self._send_pending: Optional[Tuple[np.ndarray, int]] = None # (pixels, brightness)
|
||||||
self._send_thread: Optional[threading.Thread] = None
|
self._send_thread: Optional[threading.Thread] = None
|
||||||
self._send_stop = threading.Event()
|
self._send_stop = threading.Event()
|
||||||
self._last_sent_pixels: Optional[np.ndarray] = None # for change-threshold dedup
|
self._last_sent_pixels: Optional[np.ndarray] = None
|
||||||
|
|
||||||
async def connect(self) -> bool:
|
async def connect(self) -> bool:
|
||||||
"""Connect to OpenRGB server and access the target device."""
|
"""Connect to OpenRGB server and access the target device."""
|
||||||
@@ -295,10 +295,10 @@ class OpenRGBLEDClient(LEDClient):
|
|||||||
|
|
||||||
# Change-threshold dedup — compare RAW pixels before brightness scaling
|
# Change-threshold dedup — compare RAW pixels before brightness scaling
|
||||||
# so low brightness doesn't crush differences below the threshold.
|
# so low brightness doesn't crush differences below the threshold.
|
||||||
# GPU I2C/SMBus writes cause system-wide stalls; minimizing writes is critical.
|
# Exact-match dedup — skip only if pixels are identical to last sent frame.
|
||||||
|
# Threshold-based dedup caused stutter at low brightness.
|
||||||
if self._last_sent_pixels is not None and self._last_sent_pixels.shape == pixel_array.shape:
|
if self._last_sent_pixels is not None and self._last_sent_pixels.shape == pixel_array.shape:
|
||||||
diff = np.mean(np.abs(pixel_array.astype(np.int16) - self._last_sent_pixels.astype(np.int16)))
|
if np.array_equal(pixel_array, self._last_sent_pixels):
|
||||||
if diff < 2.0:
|
|
||||||
return
|
return
|
||||||
self._last_sent_pixels = pixel_array.copy()
|
self._last_sent_pixels = pixel_array.copy()
|
||||||
|
|
||||||
|
|||||||
@@ -451,6 +451,15 @@ body.cs-drag-active .card-drag-handle {
|
|||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-url-text {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-url-badge:hover {
|
.device-url-badge:hover {
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export function createDeviceCard(device) {
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="card-title" title="${escapeHtml(device.name || device.id)}">
|
<div class="card-title" title="${escapeHtml(device.name || device.id)}">
|
||||||
<span class="health-dot ${healthClass}" title="${healthTitle}"></span>
|
<span class="health-dot ${healthClass}" title="${healthTitle}"></span>
|
||||||
${device.name || device.id}
|
<span class="card-title-text">${device.name || device.id}</span>
|
||||||
${device.url && device.url.startsWith('http') ? `<a class="device-url-badge" href="${device.url}" target="_blank" rel="noopener" title="${t('device.button.webui')}"><span class="device-url-text">${escapeHtml(device.url.replace(/^https?:\/\//, ''))}</span><span class="device-url-icon">${ICON_WEB}</span></a>` : (device.url && !device.url.startsWith('mock://') && !device.url.startsWith('ws://') && !device.url.startsWith('openrgb://') && !device.url.startsWith('http') ? `<span class="device-url-badge"><span class="device-url-text">${escapeHtml(device.url)}</span></span>` : '')}
|
${device.url && device.url.startsWith('http') ? `<a class="device-url-badge" href="${device.url}" target="_blank" rel="noopener" title="${t('device.button.webui')}"><span class="device-url-text">${escapeHtml(device.url.replace(/^https?:\/\//, ''))}</span><span class="device-url-icon">${ICON_WEB}</span></a>` : (device.url && !device.url.startsWith('mock://') && !device.url.startsWith('ws://') && !device.url.startsWith('openrgb://') && !device.url.startsWith('http') ? `<span class="device-url-badge"><span class="device-url-text">${escapeHtml(device.url)}</span></span>` : '')}
|
||||||
${healthLabel}
|
${healthLabel}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user