summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--src/gui/fpg_trayicon.pas166
9 files changed, 312 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
diff --git a/src/gui/fpg_trayicon.pas b/src/gui/fpg_trayicon.pas
new file mode 100644
index 00000000..b439f085
--- /dev/null
+++ b/src/gui/fpg_trayicon.pas
@@ -0,0 +1,166 @@
+{
+ fpGUI - Free Pascal GUI Toolkit
+
+ Copyright (C) 2006 - 2012 See the file AUTHORS.txt, included in this
+ distribution, for details of the copyright.
+
+ See the file COPYING.modifiedLGPL, included in this distribution,
+ for details about redistributing fpGUI.
+
+ 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.
+
+ Description:
+ This unit implements a class that provides an icon for an application
+ in the system tray.
+}
+unit fpg_trayicon;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ fpg_base,
+ fpg_main,
+ fpg_widget,
+ fpg_menu,
+ fpg_interface;
+
+type
+
+ TfpgMessageIconType = (mitNoIcon, mitInformation, mitWarning, mitCritical);
+
+
+ TfpgSystemTrayIcon = class(TfpgWidget)
+ private
+ FPopupMenu: TfpgPopupMenu;
+ FImageName: TfpgString;
+ FImage: TfpgImage;
+ FOnMessageClicked: TNotifyEvent;
+ procedure SetImageName(AValue: TfpgString);
+ protected
+ FSysTrayHandler: TfpgSystemTrayHandler;
+ procedure SetVisible(const AValue: boolean); override;
+ procedure HandlePaint; override;
+ procedure HandleRMouseUp(x, y: integer; shiftstate: TShiftState); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ function IsSystemTrayAvailable: boolean;
+ function SupportsMessages: boolean;
+ procedure Show;
+ procedure Hide;
+ procedure ShowMessage(const ATitle: TfpgString; const AMessage: TfpgString; const AMessageIcon: TfpgMessageIconType; const AMillisecondsTimeoutHint: Word = 10000);
+ published
+ property BackgroundColor;
+ property Hint;
+ property ImageName: TfpgString read FImageName write SetImageName;
+ property PopupMenu: TfpgPopupMenu read FPopupMenu write FPopupMenu;
+ property ShowHint;
+ property OnClick;
+ property OnMessageClicked: TNotifyEvent read FOnMessageClicked write FOnMessageClicked;
+ property OnPaint;
+ end;
+
+
+implementation
+
+{ TfpgSystemTrayIcon }
+
+procedure TfpgSystemTrayIcon.SetImageName(AValue: TfpgString);
+begin
+ if FImageName = AValue then
+ Exit;
+ FImageName := AValue;
+ Repaint;
+end;
+
+procedure TfpgSystemTrayIcon.SetVisible(const AValue: boolean);
+begin
+ if FVisible = AValue then
+ Exit;
+ FVisible := AValue;
+ if FVisible then
+ Show
+ else
+ Hide;
+end;
+
+procedure TfpgSystemTrayIcon.HandlePaint;
+var
+ img: TfpgImage;
+begin
+ inherited HandlePaint;
+ Canvas.Clear(FBackgroundColor);
+ if FImageName <> '' then
+ begin
+ { request a reference to already loaded image }
+ img := fpgImages.GetImage(FImageName);
+ if Assigned(img) then
+ begin
+ FCanvas.DrawImage((Width-img.Width) div 2, (Height-img.Height) div 2, img);
+ end;
+ end;
+end;
+
+procedure TfpgSystemTrayIcon.HandleRMouseUp(x, y: integer; shiftstate: TShiftState);
+begin
+ inherited HandleRMouseUp(x, y, shiftstate);
+ if Assigned(FPopupMenu) then
+ begin
+ FPopupMenu.ShowAt(self, x, y, True);
+ end;
+end;
+
+constructor TfpgSystemTrayIcon.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FWidth := 20;
+ FHeight := 20;
+ FVisible := False;
+
+ FHint := '';
+ FImage := nil;
+ FImageName := '';
+ FPopupMenu := nil;
+
+ FSysTrayHandler := TfpgSystemTrayHandler.Create(self);
+end;
+
+function TfpgSystemTrayIcon.IsSystemTrayAvailable: boolean;
+begin
+ Result := FSysTrayHandler.IsSystemTrayAvailable;
+end;
+
+function TfpgSystemTrayIcon.SupportsMessages: boolean;
+begin
+ { TODO : As far as I know Mac OS X doesn't support this, though they do now
+ have this Notifications functionility since 10.8 }
+ Result := FSysTrayHandler.SupportsMessages;
+end;
+
+procedure TfpgSystemTrayIcon.Show;
+begin
+ FSysTrayHandler.Show;
+ FVisible := True;
+end;
+
+procedure TfpgSystemTrayIcon.Hide;
+begin
+ { TODO : TfpgSystemTrayIcon.Hide not implemented yet! }
+// FVisible := False;
+// FSysTrayHandler.Hide;
+end;
+
+procedure TfpgSystemTrayIcon.ShowMessage(const ATitle: TfpgString;
+ const AMessage: TfpgString; const AMessageIcon: TfpgMessageIconType;
+ const AMillisecondsTimeoutHint: Word);
+begin
+ { TODO : TfpgSystemTrayIcon.ShowMessage not implemented yet! }
+end;
+
+end.
+