diff --git a/lib/core/constants.dart b/lib/core/constants.dart index 9137c75d..a5108d95 100644 --- a/lib/core/constants.dart +++ b/lib/core/constants.dart @@ -11,6 +11,8 @@ const String kPackageId = 'codes.merritt.Nyrna'; const String kTroubleshootingGuideUrl = 'https://nyrna.merritt.codes/docs/troubleshooting'; +const String kWaylandHotkeyDocsUrl = 'https://nyrna.merritt.codes/docs/hotkey/#wayland'; + const String websiteUrl = 'https://nyrna.merritt.codes/'; /// The app's package name / identifier that Windows uses when installed from diff --git a/lib/localization/app_en.arb b/lib/localization/app_en.arb index 6b659e8f..6a82ce7f 100644 --- a/lib/localization/app_en.arb +++ b/lib/localization/app_en.arb @@ -224,5 +224,13 @@ "selectApp": "Select app", "@selectApp": { "description": "Hint text for app selection dropdown" + }, + "waylandHotkeyMessage": "Global hotkeys are not supported on Wayland. You can set up a custom hotkey manually through your desktop environment.", + "@waylandHotkeyMessage": { + "description": "Message shown on Wayland explaining hotkeys must be configured manually" + }, + "waylandHotkeyDocsLink": "View setup instructions", + "@waylandHotkeyDocsLink": { + "description": "Link text for Wayland hotkey setup documentation" } } diff --git a/lib/localization/app_localizations.dart b/lib/localization/app_localizations.dart index a6117f6b..e184c285 100644 --- a/lib/localization/app_localizations.dart +++ b/lib/localization/app_localizations.dart @@ -419,6 +419,18 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Select app'** String get selectApp; + + /// Message shown on Wayland explaining hotkeys must be configured manually + /// + /// In en, this message translates to: + /// **'Global hotkeys are not supported on Wayland. You can set up a custom hotkey manually through your desktop environment.'** + String get waylandHotkeyMessage; + + /// Link text for Wayland hotkey setup documentation + /// + /// In en, this message translates to: + /// **'View setup instructions'** + String get waylandHotkeyDocsLink; } class _AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/lib/localization/app_localizations_de.dart b/lib/localization/app_localizations_de.dart index d601af86..df88aab2 100644 --- a/lib/localization/app_localizations_de.dart +++ b/lib/localization/app_localizations_de.dart @@ -172,4 +172,11 @@ class AppLocalizationsDe extends AppLocalizations { @override String get selectApp => 'Select app'; + + @override + String get waylandHotkeyMessage => + 'Global hotkeys are not supported on Wayland. You can set up a custom hotkey manually through your desktop environment.'; + + @override + String get waylandHotkeyDocsLink => 'View setup instructions'; } diff --git a/lib/localization/app_localizations_en.dart b/lib/localization/app_localizations_en.dart index 6717138a..81b65a39 100644 --- a/lib/localization/app_localizations_en.dart +++ b/lib/localization/app_localizations_en.dart @@ -172,4 +172,11 @@ class AppLocalizationsEn extends AppLocalizations { @override String get selectApp => 'Select app'; + + @override + String get waylandHotkeyMessage => + 'Global hotkeys are not supported on Wayland. You can set up a custom hotkey manually through your desktop environment.'; + + @override + String get waylandHotkeyDocsLink => 'View setup instructions'; } diff --git a/lib/localization/app_localizations_it.dart b/lib/localization/app_localizations_it.dart index 15e311db..6f46341d 100644 --- a/lib/localization/app_localizations_it.dart +++ b/lib/localization/app_localizations_it.dart @@ -173,4 +173,11 @@ class AppLocalizationsIt extends AppLocalizations { @override String get selectApp => 'Select app'; + + @override + String get waylandHotkeyMessage => + 'Global hotkeys are not supported on Wayland. You can set up a custom hotkey manually through your desktop environment.'; + + @override + String get waylandHotkeyDocsLink => 'View setup instructions'; } diff --git a/lib/localization/app_localizations_zh.dart b/lib/localization/app_localizations_zh.dart index 754f50ad..ec0c1845 100644 --- a/lib/localization/app_localizations_zh.dart +++ b/lib/localization/app_localizations_zh.dart @@ -168,4 +168,11 @@ class AppLocalizationsZh extends AppLocalizations { @override String get selectApp => '选择应用'; + + @override + String get waylandHotkeyMessage => + 'Global hotkeys are not supported on Wayland. You can set up a custom hotkey manually through your desktop environment.'; + + @override + String get waylandHotkeyDocsLink => 'View setup instructions'; } diff --git a/lib/settings/widgets/integration_section.dart b/lib/settings/widgets/integration_section.dart index 0350be9e..ee36dac0 100644 --- a/lib/settings/widgets/integration_section.dart +++ b/lib/settings/widgets/integration_section.dart @@ -3,11 +3,20 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; +import '../../app/app.dart'; import '../../apps_list/apps_list.dart'; +import '../../core/core.dart'; import '../../localization/app_localizations.dart'; +import '../../native_platform/native_platform.dart'; import '../../theme/styles.dart'; import '../settings.dart'; +// Quick hack, should be moved to a more appropriate place later. +bool _isWayland(BuildContext context) { + final sessionType = context.read().state.sessionType; + return sessionType?.displayProtocol == DisplayProtocol.wayland; +} + /// Add shortcuts and icons for portable builds or autostart. class IntegrationSection extends StatelessWidget { const IntegrationSection({super.key}); @@ -119,6 +128,33 @@ class _HotkeyConfigWidget extends StatelessWidget { @override Widget build(BuildContext context) { + if (_isWayland(context)) { + // Hotkey manager doesn't work on Wayland, so we hide the hotkey settings in that + // case. Instead show a web link to the docs about how to setup a custom hotkey + // through the DE. + return ListTile( + leading: const Icon(Icons.keyboard), + title: Text( + AppLocalizations.of(context)!.hotkey, + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)!.waylandHotkeyMessage, + ), + TextButton( + style: TextButton.styleFrom(padding: EdgeInsets.zero), + onPressed: () => context.read().launchURL(kWaylandHotkeyDocsUrl), + child: Text( + AppLocalizations.of(context)!.waylandHotkeyDocsLink, + ), + ), + ], + ), + ); + } + return ListTile( title: Text( AppLocalizations.of(context)!.hotkey, @@ -240,6 +276,11 @@ class _AppSpecificHotkeys extends StatelessWidget { @override Widget build(BuildContext context) { + if (_isWayland(context)) { + // Global hotkeys don't work on Wayland. + return const SizedBox(); + } + return BlocBuilder( builder: (context, state) { return Card(