-
Notifications
You must be signed in to change notification settings - Fork 304
feat: Add hardware acceleration toggle with restart confirmation (Desktop only) [WPB-22425] #20441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
34cd175
d2fd125
5f37984
37a3914
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,6 +22,7 @@ import {ChangeEvent, useCallback, useEffect, useRef, useState} from 'react'; | |||||||
| import type {WebappProperties} from '@wireapp/api-client/lib/user/data/'; | ||||||||
| import {amplify} from 'amplify'; | ||||||||
|
|
||||||||
| import {Runtime} from '@wireapp/commons'; | ||||||||
| import {Checkbox, CheckboxLabel} from '@wireapp/react-ui-kit'; | ||||||||
| import {WebAppEvents} from '@wireapp/webapp-events'; | ||||||||
|
|
||||||||
|
|
@@ -30,6 +31,8 @@ import type {PropertiesRepository} from 'Repositories/properties/PropertiesRepos | |||||||
| import {PROPERTIES_TYPE} from 'Repositories/properties/PropertiesType'; | ||||||||
| import {t} from 'Util/LocalizerUtil'; | ||||||||
|
|
||||||||
| import {HardwareAccelerationRestartModal} from './HardwareAccelerationRestartModal'; | ||||||||
|
|
||||||||
| import {Config} from '../../../../../Config'; | ||||||||
| import {PreferencesSection} from '../components/PreferencesSection'; | ||||||||
|
|
||||||||
|
|
@@ -54,6 +57,21 @@ const CallOptions = ({constraintsHandler, propertiesRepository}: CallOptionsProp | |||||||
| !!propertiesRepository.properties.settings.call.enable_press_space_to_unmute, | ||||||||
| ); | ||||||||
|
|
||||||||
| const desktopSettings = Config.getDesktopSettings(); | ||||||||
|
|
||||||||
| const isHardwareAccelerationChangeable = Runtime.isDesktopApp() && !!desktopSettings; | ||||||||
|
|
||||||||
| const [showHwRestartModal, setShowHwRestartModal] = useState(false); | ||||||||
| const [pendingHwValue, setPendingHwValue] = useState<boolean | null>(null); | ||||||||
|
|
||||||||
| const [hardwareAccelerationEnabled, setHardwareAccelerationEnabled] = useState<boolean>(() => { | ||||||||
| if (!isHardwareAccelerationChangeable) { | ||||||||
| return true; // default in browser (but not changeable) | ||||||||
| } | ||||||||
|
|
||||||||
| return desktopSettings.isHardwareAccelerationEnabled(); | ||||||||
| }); | ||||||||
|
|
||||||||
| useEffect(() => { | ||||||||
| const updateProperties = ({settings}: WebappProperties) => { | ||||||||
| setVbrEncoding(!isCbrEncodingEnforced && settings.call.enable_vbr_encoding); | ||||||||
|
|
@@ -102,6 +120,32 @@ const CallOptions = ({constraintsHandler, propertiesRepository}: CallOptionsProp | |||||||
| [propertiesRepository], | ||||||||
| ); | ||||||||
|
|
||||||||
| const handleHardwareAccelerationChange = useCallback((event: ChangeEvent<HTMLInputElement>) => { | ||||||||
| const isChecked = event.target.checked; | ||||||||
|
|
||||||||
| setPendingHwValue(isChecked); | ||||||||
| setShowHwRestartModal(true); | ||||||||
| }, []); | ||||||||
|
|
||||||||
| const confirmHardwareAccelerationChange = () => { | ||||||||
| if (!desktopSettings || pendingHwValue === null) { | ||||||||
| setShowHwRestartModal(false); | ||||||||
| return; | ||||||||
| } | ||||||||
|
|
||||||||
| desktopSettings.setHardwareAccelerationEnabled(pendingHwValue); | ||||||||
| setHardwareAccelerationEnabled(pendingHwValue); | ||||||||
|
|
||||||||
| setShowHwRestartModal(false); | ||||||||
|
|
||||||||
| amplify.publish(WebAppEvents.LIFECYCLE.RESTART); | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if restart is delayed then
Suggested change
|
||||||||
| }; | ||||||||
|
|
||||||||
| const cancelHardwareAccelerationChange = () => { | ||||||||
| setShowHwRestartModal(false); | ||||||||
| setPendingHwValue(null); | ||||||||
| }; | ||||||||
|
|
||||||||
| return ( | ||||||||
| <PreferencesSection title={t('preferencesOptionsCall')}> | ||||||||
| <div> | ||||||||
|
|
@@ -153,6 +197,29 @@ const CallOptions = ({constraintsHandler, propertiesRepository}: CallOptionsProp | |||||||
| </p> | ||||||||
| </div> | ||||||||
| )} | ||||||||
|
|
||||||||
| {isHardwareAccelerationChangeable && ( | ||||||||
| <div className="checkbox-margin"> | ||||||||
| <Checkbox | ||||||||
| onChange={handleHardwareAccelerationChange} | ||||||||
| checked={hardwareAccelerationEnabled} | ||||||||
| data-uie-name="status-preference-hardware-acceleration" | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the htmlFor attribute in the
Suggested change
|
||||||||
| > | ||||||||
| <CheckboxLabel htmlFor="status-preference-hardware-acceleration"> | ||||||||
| {t('preferencesOptionsEnableHardwareAcceleration')} | ||||||||
| </CheckboxLabel> | ||||||||
| </Checkbox> | ||||||||
| <p className="preferences-detail preferences-detail-intended"> | ||||||||
| {t('preferencesOptionsEnableHardwareAccelerationDetails')} | ||||||||
| </p> | ||||||||
| </div> | ||||||||
| )} | ||||||||
|
|
||||||||
| <HardwareAccelerationRestartModal | ||||||||
| isShown={showHwRestartModal} | ||||||||
| onCancel={cancelHardwareAccelerationChange} | ||||||||
| onConfirm={confirmHardwareAccelerationChange} | ||||||||
| /> | ||||||||
| </PreferencesSection> | ||||||||
| ); | ||||||||
| }; | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /* | ||
| * Wire | ||
| * Copyright (C) 2026 Wire Swiss GmbH | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see http://www.gnu.org/licenses/. | ||
| * | ||
| */ | ||
|
|
||
| import {ModalComponent} from 'Components/Modals/ModalComponent'; | ||
| import {t} from 'Util/LocalizerUtil'; | ||
|
|
||
| interface HardwareAccelerationRestartModalProps { | ||
| isShown: boolean; | ||
| onCancel: () => void; | ||
| onConfirm: () => void; | ||
| } | ||
|
|
||
| const HardwareAccelerationRestartModal = ({isShown, onCancel, onConfirm}: HardwareAccelerationRestartModalProps) => { | ||
| return ( | ||
| <ModalComponent isShown={isShown} onBgClick={onCancel}> | ||
| <div style={{padding: 24, maxWidth: 420}}> | ||
| <h3>{t('preferencesOptionsEnableHardwareAccelerationModalTitle')}</h3> | ||
|
|
||
| <p>{t('preferencesOptionsEnableHardwareAccelerationModalMessage')}</p> | ||
|
|
||
| <div style={{display: 'flex', justifyContent: 'flex-end', gap: 12}}> | ||
| <button onClick={onCancel}>{t('preferencesOptionsEnableHardwareAccelerationModalCancel')}</button> | ||
|
|
||
| <button onClick={onConfirm}>{t('preferencesOptionsEnableHardwareAccelerationModalOk')}</button> | ||
| </div> | ||
| </div> | ||
| </ModalComponent> | ||
| ); | ||
| }; | ||
|
|
||
| export {HardwareAccelerationRestartModal}; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -717,13 +717,6 @@ declare module 'I18n/en-US.json' { | |
| 'conversationFileUploadOverlayDescription': `Drag & drop to add files`; | ||
| 'conversationFileUploadOverlayTitle': `Upload files`; | ||
| 'conversationFileVideoPreviewLabel': `Video file preview for: {src}`; | ||
| 'conversationFilterDrafts': `Drafts`; | ||
| 'conversationFilterMentions': `Mentions`; | ||
| 'conversationFilterNone': `No filter`; | ||
| 'conversationFilterPings': `Pings`; | ||
| 'conversationFilterReplies': `Replies`; | ||
| 'conversationFilterTooltip': `Filter conversations`; | ||
| 'conversationFilterUnread': `Unread`; | ||
| 'conversationFoldersEmptyText': `Add your conversations to folders to stay organized.`; | ||
| 'conversationFoldersEmptyTextLearnMore': `Learn more`; | ||
| 'conversationFooterArchive': `Archive`; | ||
|
|
@@ -1692,6 +1685,12 @@ declare module 'I18n/en-US.json' { | |
| 'preferencesOptionsEmojiReplaceDetail': `:-) → [icon]`; | ||
| 'preferencesOptionsEnableAgcCheckbox': `Automatic gain control (AGC)`; | ||
| 'preferencesOptionsEnableAgcDetails': `Enable to allow your microphone volume to be adjusted automatically to ensure all participants in a call are heard with similar and comfortable loudness.`; | ||
| 'preferencesOptionsEnableHardwareAcceleration': `Enable Hardware Acceleration (Recommended)`; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These keys must also be added in the |
||
| 'preferencesOptionsEnableHardwareAccelerationDetails': `When enabled, hardware acceleration allows the webcam to use your device’s GPU to improve video performance and reduce CPU usage. This can result in smoother video playback, better responsiveness, and improved overall stability.\nThis option is enabled by default and is recommended for most systems. Disable it only if you experience compatibility or display issues.\nA restart of the application is required for changes to take effect.`; | ||
| 'preferencesOptionsEnableHardwareAccelerationModalTitle': `Restart required`; | ||
| 'preferencesOptionsEnableHardwareAccelerationModalMessage': `Changing the hardware acceleration setting requires a restart of the application. The app will close and reopen automatically. Do you want to restart now?`; | ||
| 'preferencesOptionsEnableHardwareAccelerationModalCancel': `Cancel`; | ||
| 'preferencesOptionsEnableHardwareAccelerationModalOk': `Restart now`; | ||
| 'preferencesOptionsEnablePressSpaceToUnmute': `Unmute with space bar`; | ||
| 'preferencesOptionsEnablePressSpaceToUnmuteDetails': `Enable to unmute your microphone by pressing and holding the space bar as long as you want to speak. You can use this option in full view.`; | ||
| 'preferencesOptionsEnableSoundlessIncomingCalls': `Silence other calls`; | ||
|
|
@@ -1798,6 +1797,7 @@ declare module 'I18n/en-US.json' { | |
| 'searchCreateGroup': `Create group`; | ||
| 'searchCreateGuestRoom': `Create guest room`; | ||
| 'searchDirectConversations': `Search 1:1 conversations`; | ||
| 'searchDraftsConversations': `Search in drafts`; | ||
| 'searchFavoriteConversations': `Search favorites`; | ||
| 'searchFederatedDomainNotAvailable': `The federated domain is currently not available.`; | ||
| 'searchFederatedDomainNotAvailableLearnMore': `Learn more`; | ||
|
|
@@ -1816,6 +1816,7 @@ declare module 'I18n/en-US.json' { | |
| 'searchManageServices': `Manage Apps`; | ||
| 'searchManageServicesNoResults': `Manage apps`; | ||
| 'searchMemberInvite': `Invite people to join the team`; | ||
| 'searchMentionsConversations': `Search in mentions`; | ||
| 'searchNoContactsOnWire': `You have no contacts on {brandName}.\nTry finding people by\nname or username.`; | ||
| 'searchNoMatchesPartner': `No results`; | ||
| 'searchNoServicesManager': `Apps are helpers that can improve your workflow.`; | ||
|
|
@@ -1826,6 +1827,8 @@ declare module 'I18n/en-US.json' { | |
| 'searchPeople': `People`; | ||
| 'searchPeopleOnlyPlaceholder': `Search people`; | ||
| 'searchPeoplePlaceholder': `Search for people and conversations`; | ||
| 'searchPingsConversations': `Search in pings`; | ||
| 'searchRepliesConversations': `Search in replies`; | ||
| 'searchServiceConfirmButton': `Open Conversation`; | ||
| 'searchServicePlaceholder': `Search by name`; | ||
| 'searchServices': `Apps`; | ||
|
|
@@ -1835,6 +1838,7 @@ declare module 'I18n/en-US.json' { | |
| 'searchTrySearch': `Find people by\nname or username`; | ||
| 'searchTrySearchFederation': `Find people in Wire by name or\n@username\n\nFind people from another domain\nby @username@domainname`; | ||
| 'searchTrySearchLearnMore': `Learn more`; | ||
| 'searchUnreadConversations': `Search in unread`; | ||
| 'selectAccountTypeHeading': `How will you use Wire?`; | ||
| 'selectPersonalAccountTypeOptionButtonText': `Create Personal Account`; | ||
| 'selectPersonalAccountTypeOptionDescription': `Chat with friends and family.`; | ||
|
|
@@ -1885,6 +1889,8 @@ declare module 'I18n/en-US.json' { | |
| 'success.openWebAppText': `Open Wire for web`; | ||
| 'success.subheader': `What do you want to do next?`; | ||
| 'systemMessageLearnMore': `Learn more`; | ||
| 'tabsFilterHeader': `Show filters`; | ||
| 'tabsFilterTooltip': `Customize visible tabs`; | ||
| 'takeoverButtonChoose': `Choose your own`; | ||
| 'takeoverButtonKeep': `Keep this one`; | ||
| 'takeoverLink': `Learn more`; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.