summaryrefslogtreecommitdiff
path: root/src/corelib
diff options
context:
space:
mode:
authorGraeme Geldenhuys <graeme@mastermaths.co.za>2012-10-26 16:57:47 +0100
committerGraeme Geldenhuys <graeme@mastermaths.co.za>2012-10-26 17:03:38 +0100
commit1e8c032fb7e7d6712c161a34965a6ccdd89371b1 (patch)
tree0f9b947203f6a257201992521dee642ec406c2e4 /src/corelib
parent4042c15028970e1d40ce3a06943a9fc4dbc3c0e2 (diff)
downloadfpGUI-1e8c032fb7e7d6712c161a34965a6ccdd89371b1.tar.xz
Adds a System Tray Icon implementation for X11.
This has been a long awaited feature. There is still some functionality missing and some more tweaks that need to be applied, but this implementation does work. It has been tested under JWM (Joe's Window Manager), MATE (Gnome2 fork) and KDE 4.8.x The Windows implementation will follow shortly.
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/gdi/fpg_gdi.pas41
-rw-r--r--src/corelib/gdi/fpg_interface.pas1
-rw-r--r--src/corelib/gdi/fpgui_toolkit.lpk6
-rw-r--r--src/corelib/gdi/fpgui_toolkit.pas2
-rw-r--r--src/corelib/x11/fpg_interface.pas1
-rw-r--r--src/corelib/x11/fpg_x11.pas93
-rw-r--r--src/corelib/x11/fpgui_toolkit.lpk7
-rw-r--r--src/corelib/x11/fpgui_toolkit.pas2
8 files changed, 146 insertions, 7 deletions
diff --git a/src/corelib/gdi/fpg_gdi.pas b/src/corelib/gdi/fpg_gdi.pas
index 311a4fce..fec0c511 100644
--- a/src/corelib/gdi/fpg_gdi.pas
+++ b/src/corelib/gdi/fpg_gdi.pas
@@ -304,8 +304,6 @@ type
end;
- { TfpgGDITimer }
-
TfpgGDITimer = class(TfpgBaseTimer)
private
FHandle: THandle;
@@ -316,6 +314,16 @@ type
end;
+ TfpgGDISystemTrayIcon = class(TfpgComponent)
+ public
+ constructor Create(AOwner: TComponent); override;
+ procedure Show;
+ procedure Hide;
+ function IsSystemTrayAvailable: boolean;
+ function SupportsMessages: boolean;
+ end;
+
+
implementation
uses
@@ -3105,6 +3113,35 @@ begin
end;
+{ TfpgGDISystemTrayIcon }
+
+constructor TfpgGDISystemTrayIcon.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+end;
+
+procedure TfpgGDISystemTrayIcon.Show;
+begin
+ //
+end;
+
+procedure TfpgGDISystemTrayIcon.Hide;
+begin
+ //
+end;
+
+function TfpgGDISystemTrayIcon.IsSystemTrayAvailable: boolean;
+begin
+ Result := False;
+end;
+
+function TfpgGDISystemTrayIcon.SupportsMessages: boolean;
+begin
+ Result := True;
+end;
+
+
+
initialization
wapplication := nil;
MouseFocusedWH := 0;
diff --git a/src/corelib/gdi/fpg_interface.pas b/src/corelib/gdi/fpg_interface.pas
index 8833f44d..5d5d4833 100644
--- a/src/corelib/gdi/fpg_interface.pas
+++ b/src/corelib/gdi/fpg_interface.pas
@@ -36,6 +36,7 @@ type
TfpgMimeDataImpl = class(TfpgGDIMimeDataBase);
TfpgDragImpl = class(TfpgGDIDrag);
TfpgTimerImpl = class(TfpgGDITimer);
+ TfpgSystemTrayHandler = class(TfpgGDISystemTrayIcon);
implementation
diff --git a/src/corelib/gdi/fpgui_toolkit.lpk b/src/corelib/gdi/fpgui_toolkit.lpk
index a4f927c2..7654d0d4 100644
--- a/src/corelib/gdi/fpgui_toolkit.lpk
+++ b/src/corelib/gdi/fpgui_toolkit.lpk
@@ -32,7 +32,7 @@
<Description Value="fpGUI Toolkit"/>
<License Value="LGPL 2 with static linking exception."/>
<Version Minor="8"/>
- <Files Count="96">
+ <Files Count="97">
<Item1>
<Filename Value="..\stdimages.inc"/>
<Type Value="Include"/>
@@ -417,6 +417,10 @@
<Filename Value="..\..\reportengine\u_visu.pas"/>
<UnitName Value="U_Visu"/>
</Item96>
+ <Item97>
+ <Filename Value="..\..\gui\fpg_trayicon.pas"/>
+ <UnitName Value="fpg_trayicon"/>
+ </Item97>
</Files>
<LazDoc Paths="../../../docs/xml/corelib;../../../docs/xml/corelib/x11;../../../docs/xml/corelib/gdi;../../../docs/xml/gui"/>
<RequiredPkgs Count="1">
diff --git a/src/corelib/gdi/fpgui_toolkit.pas b/src/corelib/gdi/fpgui_toolkit.pas
index 5caa6228..7496bb18 100644
--- a/src/corelib/gdi/fpgui_toolkit.pas
+++ b/src/corelib/gdi/fpgui_toolkit.pas
@@ -21,7 +21,7 @@ uses
fpg_interface, fpg_editbtn, fpg_imgfmt_jpg, fpg_imgutils, fpg_stylemanager,
fpg_style_win2k, fpg_style_motif, fpg_style_clearlooks, fpg_style_bluecurve,
fpg_style_bitmap, fpg_readonly, fpg_imgfmt_png, U_Command, U_Pdf, U_Report,
- U_ReportImages, U_Visu;
+ U_ReportImages, U_Visu, fpg_trayicon;
implementation
diff --git a/src/corelib/x11/fpg_interface.pas b/src/corelib/x11/fpg_interface.pas
index 6f216179..aa30039f 100644
--- a/src/corelib/x11/fpg_interface.pas
+++ b/src/corelib/x11/fpg_interface.pas
@@ -36,6 +36,7 @@ type
TfpgMimeDataImpl = class(TfpgX11MimeData);
TfpgDragImpl = class(TfpgX11Drag);
TfpgTimerImpl = class(TfpgX11Timer);
+ TfpgSystemTrayHandler = class(TfpgX11SystemTrayHandler);
implementation
diff --git a/src/corelib/x11/fpg_x11.pas b/src/corelib/x11/fpg_x11.pas
index d1e83d93..046b2f74 100644
--- a/src/corelib/x11/fpg_x11.pas
+++ b/src/corelib/x11/fpg_x11.pas
@@ -118,6 +118,10 @@ const
MWM_INPUT_SYSTEM_MODAL = 2;
MWM_INPUT_FULL_APPLICATION_MODAL = 3;
PROP_MWM_HINTS_ELEMENTS = 5;
+// System Tray message opcodes
+ SYSTEM_TRAY_REQUEST_DOCK = 0;
+ SYSTEM_TRAY_BEGIN_MESSAGE = 1;
+ SYSTEM_TRAY_CANCEL_MESSAGE = 2;
type
TXWindowStateFlag = (xwsfMapped);
@@ -392,6 +396,23 @@ type
end;
+ TfpgX11SystemTrayHandler = class(TfpgComponent)
+ private
+ FTrayIconParent: TWindow;
+ FTrayWidget: TfpgWindowBase;
+ function GetTrayIconParent: TWindow;
+ function GetSysTrayWindow: TWindow;
+ function Send_Message(dest: TWindow; msg: longword; data1, data2, data3: longword): boolean;
+ property TrayIconParent: TWindow read GetTrayIconParent;
+ public
+ constructor Create(AOwner: TComponent); override;
+ procedure Show;
+ procedure Hide;
+ function IsSystemTrayAvailable: boolean;
+ function SupportsMessages: boolean;
+ end;
+
+
function fpgColorToX(col: TfpgColor): longword;
@@ -3674,6 +3695,78 @@ begin
end;
end;
+{ TfpgX11SystemTrayHandler }
+
+function TfpgX11SystemTrayHandler.GetTrayIconParent: TWindow;
+begin
+ if FTrayIconParent = None then
+ FTrayIconParent := GetSysTrayWindow;
+ Result := FTrayIconParent;
+end;
+
+function TfpgX11SystemTrayHandler.GetSysTrayWindow: TWindow;
+var
+ buf: array[0..32] of char;
+ selection_atom: TAtom;
+begin
+ XGrabServer(xapplication.Display);
+
+ buf := PChar('_NET_SYSTEM_TRAY_S' + IntToStr(xapplication.DefaultScreen));
+ selection_atom := XInternAtom(xapplication.Display, buf, false);
+ Result := XGetSelectionOwner(xapplication.Display, selection_atom);
+
+ XUngrabServer(xapplication.Display);
+end;
+
+function TfpgX11SystemTrayHandler.Send_Message(dest: TWindow; msg: longword; data1, data2, data3: longword): boolean;
+var
+ ev: TXEvent;
+begin
+ FillChar(ev, SizeOf(TXEvent), 0);
+
+ ev.xclient._type := ClientMessage;
+ ev.xclient.window := dest; { sender (tray icon window) }
+ ev.xclient.message_type := XInternAtom(xapplication.Display, '_NET_SYSTEM_TRAY_OPCODE', False );
+ ev.xclient.format := 32;
+
+ ev.xclient.data.l[0] := CurrentTime;
+ ev.xclient.data.l[1] := msg; { message opcode }
+ ev.xclient.data.l[2] := data1;
+ ev.xclient.data.l[3] := data2;
+ ev.xclient.data.l[4] := data3;
+
+ Result := XSendEvent(xapplication.Display, TrayIconParent, False, NoEventMask, @ev) <> 0;
+ XSync(xapplication.Display, False);
+end;
+
+procedure TfpgX11SystemTrayHandler.Show;
+begin
+ Send_Message(TrayIconParent, SYSTEM_TRAY_REQUEST_DOCK, TfpgX11Window(Owner).WinHandle, 0, 0);
+end;
+
+procedure TfpgX11SystemTrayHandler.Hide;
+begin
+ TfpgX11Window(FTrayWidget).DoSetWindowVisible(False);
+end;
+
+constructor TfpgX11SystemTrayHandler.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FTrayWidget := AOwner as TfpgWindowBase;
+ FTrayIconParent := None;
+end;
+
+function TfpgX11SystemTrayHandler.IsSystemTrayAvailable: boolean;
+begin
+ Result := GetSysTrayWindow <> None;
+end;
+
+function TfpgX11SystemTrayHandler.SupportsMessages: boolean;
+begin
+ Result := True;
+end;
+
+
initialization
xapplication := nil;
diff --git a/src/corelib/x11/fpgui_toolkit.lpk b/src/corelib/x11/fpgui_toolkit.lpk
index dd6750db..5e61d76c 100644
--- a/src/corelib/x11/fpgui_toolkit.lpk
+++ b/src/corelib/x11/fpgui_toolkit.lpk
@@ -2,7 +2,6 @@
<CONFIG>
<Package Version="4">
<Name Value="fpgui_toolkit"/>
- <AddToProjectUsesSection Value="False"/>
<Author Value="Graeme Geldenhuys"/>
<CompilerOptions>
<Version Value="11"/>
@@ -30,7 +29,7 @@
<Description Value="fpGUI Toolkit"/>
<License Value="LGPL 2 with static linking exception."/>
<Version Minor="8"/>
- <Files Count="97">
+ <Files Count="98">
<Item1>
<Filename Value="../stdimages.inc"/>
<Type Value="Include"/>
@@ -419,6 +418,10 @@
<Filename Value="../../reportengine/u_visu.pas"/>
<UnitName Value="U_Visu"/>
</Item97>
+ <Item98>
+ <Filename Value="../../gui/fpg_trayicon.pas"/>
+ <UnitName Value="fpg_trayicon"/>
+ </Item98>
</Files>
<LazDoc Paths="../../../docs/xml/corelib;../../../docs/xml/corelib/x11;../../../docs/xml/corelib/gdi;../../../docs/xml/gui"/>
<RequiredPkgs Count="1">
diff --git a/src/corelib/x11/fpgui_toolkit.pas b/src/corelib/x11/fpgui_toolkit.pas
index 1f957d56..a9fcc500 100644
--- a/src/corelib/x11/fpgui_toolkit.pas
+++ b/src/corelib/x11/fpgui_toolkit.pas
@@ -20,7 +20,7 @@ uses
fpg_interface, fpg_editbtn, fpg_imgfmt_jpg, fpg_imgutils, fpg_stylemanager,
fpg_style_win2k, fpg_style_motif, fpg_style_clearlooks, fpg_style_bluecurve,
fpg_style_bitmap, fpg_readonly, fpg_imgfmt_png, U_Command, U_Pdf, U_Report,
- U_ReportImages, U_Visu;
+ U_ReportImages, U_Visu, fpg_trayicon;
implementation