LCL-GTK2: Support Ayatana AppIndicator for TrayIcon. Issue #38909, patch by David.

git-svn-id: trunk@65119 -
This commit is contained in:
juha 2021-05-21 09:35:17 +00:00
parent 65fe745451
commit 876714be01

View File

@ -11,6 +11,7 @@ unit UnityWSCtrls;
interface interface
{$mode delphi} {$mode delphi}
uses uses
GLib2, Gtk2, Gdk2Pixbuf, GLib2, Gtk2, Gdk2Pixbuf,
Classes, SysUtils, dynlibs, Classes, SysUtils, dynlibs,
@ -20,6 +21,10 @@ uses
{ Copyleft implementation of TTrayIcon originally for Unity applications indicators { Copyleft implementation of TTrayIcon originally for Unity applications indicators
Original version 2015 by Anthony Walter sysrpl@gmail.com Original version 2015 by Anthony Walter sysrpl@gmail.com
Updated May 2021 to try first the Canonical libappindicator3-1 (Fedora Gnome)
then libayatana-appindicator3-1 (Debian Bullseye). Ayatana is a fork of the
Canonical one, does not mention Unity or Ubuntu (very much). DRB
Changed October 2019, we now try and identify those Linux distributions that Changed October 2019, we now try and identify those Linux distributions that
need to use LibAppIndicator3 and allow the remainder to use the older and need to use LibAppIndicator3 and allow the remainder to use the older and
more functional SystemTray. Only a few old distributions can use LibAppIndicator_1 more functional SystemTray. Only a few old distributions can use LibAppIndicator_1
@ -27,7 +32,7 @@ uses
The 'look up table' in NeedAppIndicator() can be overridden. The 'look up table' in NeedAppIndicator() can be overridden.
Introduce an optional env var, LAZUSEAPPIND that can be unset or set to Introduce an optional env var, LAZUSEAPPIND that can be unset or set to
YES, NO or INFO - YES forces an attempt to use LibAppIndicator3, NO prevents YES, NO or INFO - YES forces an attempt to use one of the AppIndicator3, NO prevents
an attempt, any non blank value (eg INFO) displays to std out what is happening. an attempt, any non blank value (eg INFO) displays to std out what is happening.
Note we assume this env var will only be used in Linux were its always safe to Note we assume this env var will only be used in Linux were its always safe to
@ -65,14 +70,15 @@ type
class function GetPosition(const {%H-}ATrayIcon: TCustomTrayIcon): TPoint; override; class function GetPosition(const {%H-}ATrayIcon: TCustomTrayIcon): TPoint; override;
end; end;
{ UnityAppIndicatorInit returns true if libappindicator_3 library can be loaded } { UnityAppIndicatorInit returns true if an AppIndicator library can be loaded }
function UnityAppIndicatorInit: Boolean; function UnityAppIndicatorInit: Boolean;
implementation implementation
const const
libappindicator_3 = 'libappindicator3.so.1'; libappindicator_3 = 'libappindicator3.so.1'; // Canonical's Unity Appindicator3 library
LibAyatanaAppIndicator = 'libayatana-appindicator3.so.1'; // Ayatana - typically called libayatana-appindicator3-1
{const {const
APP_INDICATOR_SIGNAL_NEW_ICON = 'new-icon'; APP_INDICATOR_SIGNAL_NEW_ICON = 'new-icon';
@ -299,25 +305,36 @@ begin
Exit(True); Exit(True);
UseAppInd := getEnvironmentVariable('LAZUSEAPPIND'); UseAppInd := getEnvironmentVariable('LAZUSEAPPIND');
if UseAppInd = 'NO' then if UseAppInd = 'NO' then
begin begin
Initialized := False; Initialized := False;
writeln('APPIND Debug : Choosing to not try AppIndicator3'); writeln('APPIND Debug : Choosing to use Traditional SysTray');
Exit; Exit;
end; end;
if (UseAppInd <> 'YES') and (not NeedAppIndicator()) then // ie its NO or blank or INFO if (UseAppInd <> 'YES') and (not NeedAppIndicator()) then // ie its NO or blank or INFO
begin begin
Initialized := False; Initialized := False;
if UseAppInd <> '' then if UseAppInd <> '' then
writeln('APPIND Debug : Will not use AppIndicator3'); writeln('APPIND Debug : Will use Traditional SysTray');
Exit; Exit;
end; end;
if UseAppInd = 'YES' then // either a YES or OS needs it if UseAppInd = 'YES' then // either a YES or OS needs it
writeln('APPIND Debug : Will try to force AppIndicator3') writeln('APPIND Debug : Will try to force AppIndicator3')
else else
if UseAppInd <> '' then writeln('APPIND Debug : OS and Desktop request AppIndicator3'); if UseAppInd <> '' then
writeln('APPIND Debug : OS and Desktop request AppIndicator');
Module := LoadLibrary(libappindicator_3); // might have several package names, see wiki Module := LoadLibrary(libappindicator_3); // might have several package names, see wiki
if Module = 0 then if Module = 0 then begin
Exit; if UseAppInd <> '' then // either a YES or OS needs it
writeln('APPIND Debug : Failed to load Unity AppIndicator, will try Ayatana');
Module := LoadLibrary(LibAyatanaAppIndicator);
if Module = 0 then begin
if UseAppInd <> '' then
writeln('APPIND Debug : Failed to load Ayatana AppIndicator, its likely no SysTray available.');
exit(False);
end;
end;
Result := Result :=
TryLoad('app_indicator_get_type', @app_indicator_get_type) and TryLoad('app_indicator_get_type', @app_indicator_get_type) and
TryLoad('app_indicator_new', @app_indicator_new) and TryLoad('app_indicator_new', @app_indicator_new) and
@ -340,7 +357,7 @@ begin
TryLoad('app_indicator_get_label_guide', @app_indicator_get_label_guide) and TryLoad('app_indicator_get_label_guide', @app_indicator_get_label_guide) and
TryLoad('app_indicator_get_ordering_index', @app_indicator_get_ordering_index); TryLoad('app_indicator_get_ordering_index', @app_indicator_get_ordering_index);
if UseAppInd <> '' then if UseAppInd <> '' then
writeln('APPIND Debug : AppIndicator3 has loaded ' + booltostr(Result, True)); writeln('APPIND Debug : An AppIndicator has loaded ' + booltostr(Result, True));
Initialized := Result; Initialized := Result;
end; end;