From 2697cd15fa36e413b20cc56f3b95fe6cf14eb491 Mon Sep 17 00:00:00 2001 From: Kristen McWilliam <9575627+Merrit@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:06:09 -0400 Subject: [PATCH] fix: Hide hotkey settings on Wayland and link to docs Global hotkeys are still not supported on Wayland, and the hotkey manager doesn't work at all in that environment. This change hides the hotkey settings when running on Wayland, and instead shows a message explaining the situation and linking to the docs about how to set up a custom hotkey through the DE. Resolves https://github.com/Merrit/nyrna/issues/259 --- lib/core/constants.dart | 2 + lib/localization/app_en.arb | 8 ++++ lib/localization/app_localizations.dart | 12 ++++++ lib/localization/app_localizations_de.dart | 7 ++++ lib/localization/app_localizations_en.dart | 7 ++++ lib/localization/app_localizations_it.dart | 7 ++++ lib/localization/app_localizations_zh.dart | 7 ++++ lib/settings/widgets/integration_section.dart | 41 +++++++++++++++++++ 8 files changed, 91 insertions(+) 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(