mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 18:39:10 +02:00
Added gtk1 implementation for TTrayIcon.
git-svn-id: trunk@12109 -
This commit is contained in:
parent
b3c5d076d2
commit
b8ea56b203
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2749,6 +2749,7 @@ lcl/interfaces/gtk/gtk1extra.inc svneol=native#text/pascal
|
||||
lcl/interfaces/gtk/gtk1extrah.inc svneol=native#text/pascal
|
||||
lcl/interfaces/gtk/gtk1memostrings.inc svneol=native#text/pascal
|
||||
lcl/interfaces/gtk/gtk1memostringsh.inc svneol=native#text/pascal
|
||||
lcl/interfaces/gtk/gtk1trayicon.inc -text
|
||||
lcl/interfaces/gtk/gtk1wsprivate.pp svneol=native#text/pascal
|
||||
lcl/interfaces/gtk/gtkcallback.inc svneol=native#text/pascal
|
||||
lcl/interfaces/gtk/gtkcomboboxcallback.inc svneol=native#text/pascal
|
||||
|
318
lcl/interfaces/gtk/gtk1trayicon.inc
Normal file
318
lcl/interfaces/gtk/gtk1trayicon.inc
Normal file
@ -0,0 +1,318 @@
|
||||
{%MainUnit gtkwsextctrls.pp}
|
||||
{
|
||||
gtk1trayicon.pas
|
||||
|
||||
*****************************************************************************
|
||||
* *
|
||||
* See the file COPYING.modifiedLGPL, included in this distribution, *
|
||||
* for details about the copyright. *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
*****************************************************************************
|
||||
|
||||
Authors: Felipe Monteiro de Carvalho and Andrew Haines
|
||||
|
||||
Special thanks for: Danny Milosavljevic and the Lazarus Team
|
||||
|
||||
Gtk1 specific code. Works on gnome also.
|
||||
}
|
||||
|
||||
{ TGtkWSCustomTrayIcon }
|
||||
|
||||
type
|
||||
TGtk1TrayIconHandle = class(TObject)
|
||||
public
|
||||
fDisplay: PDisplay;
|
||||
fWindow: TWindow;
|
||||
fScreen: PScreen;
|
||||
fScreenID: longint;
|
||||
fTrayParent: TWindow;
|
||||
fOwner: TComponent;
|
||||
GtkForm: TForm;
|
||||
fEmbedded: Boolean;
|
||||
fMsgCount: Integer;
|
||||
fTrayIcon: TCustomTrayIcon;
|
||||
function Send_Message(window: TWindow; msg: Integer;data1, data2,data3: Integer): boolean;
|
||||
procedure SetEmbedded;
|
||||
procedure CreateForm(id: Integer);
|
||||
procedure SetMinSize(AWidth, AHeight: Integer);
|
||||
procedure PaintForm(Sender: TObject);
|
||||
end;
|
||||
|
||||
const
|
||||
SYSTEM_TRAY_REQUEST_DOCK = 0;
|
||||
SYSTEM_TRAY_BEGIN_MESSAGE = 1;
|
||||
SYSTEM_TRAY_CANCEL_MESSAGE = 2;
|
||||
|
||||
// Temp ErrorHandler
|
||||
function TempX11ErrorHandler(Display:PDisplay; ErrorEv:PXErrorEvent):longint;cdecl;
|
||||
begin
|
||||
WriteLn('Error: ' + IntToStr(ErrorEv^.error_code));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
||||
{*******************************************************************
|
||||
* TGtk1TrayIconHandle.Send_Message ()
|
||||
*
|
||||
* DESCRIPTION: Sends a message to the X client
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
function TGtk1TrayIconHandle.Send_Message(window: TWindow; msg: Integer;data1, data2,data3: Integer): boolean;
|
||||
var
|
||||
Ev: TXEvent;
|
||||
// fmt: Integer;
|
||||
begin
|
||||
FillChar(Ev, SizeOf(TXEvent), $0);
|
||||
|
||||
ev.xclient._type := ClientMessage;
|
||||
ev.xclient.window := window;
|
||||
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False );
|
||||
ev.xclient.format := 32;
|
||||
ev.xclient.data.l[0] := CurrentTime;
|
||||
ev.xclient.data.l[1] := msg;
|
||||
ev.xclient.data.l[2] := data1;
|
||||
ev.xclient.data.l[3] := data2;
|
||||
ev.xclient.data.l[4] := data3;
|
||||
|
||||
XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev);
|
||||
XSync(fDisplay, False);
|
||||
Result := false;//(untrap_errors() = 0);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtk1TrayIconHandle.SetEmbedded ()
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TGtk1TrayIconHandle.SetEmbedded;
|
||||
var
|
||||
old_error: TXErrorHandler;
|
||||
buf: array [0..32] of char;
|
||||
selection_atom : TAtom;
|
||||
begin
|
||||
old_error := XSetErrorHandler(@TempX11ErrorHandler);
|
||||
Sleep(80);
|
||||
xsync(fdisplay,true);
|
||||
buf := PChar('_NET_SYSTEM_TRAY_S' + IntToStr(fScreenID));
|
||||
selection_atom := XInternAtom(fDisplay, buf, false);
|
||||
XGrabServer(fDisplay);
|
||||
fTrayParent := XGetSelectionOwner(fDisplay, selection_atom);
|
||||
if fTrayParent <> None then
|
||||
begin
|
||||
XSelectInput(fDisplay, fTrayParent, StructureNotifyMask);
|
||||
end;
|
||||
XUngrabServer(fDisplay);
|
||||
XFlush(fDisplay);
|
||||
|
||||
if fTrayParent <> None then
|
||||
Send_Message(fTrayParent, SYSTEM_TRAY_REQUEST_DOCK, fWindow, 0, 0);
|
||||
|
||||
XSetErrorHandler(old_error);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtk1TrayIconHandle.CreateForm ()
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TGtk1TrayIconHandle.CreateForm(id: Integer);
|
||||
begin
|
||||
GtkForm := TForm.Create(nil);
|
||||
fEmbedded := False;
|
||||
//fWindow := GDK_WINDOW_XWINDOW (Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
||||
//SHowMessage(IntToStr(Integer(fWindow)));
|
||||
//GtkForm.Parent := TWinConTrol(fOwner);
|
||||
GtkForm.WindowState := wsMinimized;
|
||||
GtkForm.BorderStyle := bsNone; //without this gnome will make a 1 pixel wide window!
|
||||
//GtkForm.Canvas.AutoRedraw := True; //not working :(
|
||||
|
||||
// needed because some things aparently don't get fully initialized until
|
||||
// visible at least once! This is Gtk related NOT LCL related.
|
||||
GtkForm.Visible :=True;
|
||||
GtkForm.Width := 22;
|
||||
GtkForm.Height := 22;
|
||||
GtkForm.Visible := False;
|
||||
|
||||
Application.ProcessMessages;
|
||||
|
||||
fDisplay := GDK_WINDOW_XDISPLAY(Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
||||
fWindow := GDK_WINDOW_XWINDOW (Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
||||
fScreen := XDefaultScreenOfDisplay(fDisplay); // get the screen
|
||||
fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtk1TrayIconHandle.SetMinSize ()
|
||||
*
|
||||
* DESCRIPTION: Attemps to avoid problems on Gnome
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TGtk1TrayIconHandle.SetMinSize(AWidth, AHeight: Integer);
|
||||
var
|
||||
size_hints: TXSizeHints;
|
||||
begin
|
||||
FillChar(size_hints, SizeOf(TXSizeHints), $0);
|
||||
|
||||
size_hints.flags := PSize or PMinSize or PMaxSize;
|
||||
size_hints.min_width := AWidth;
|
||||
size_hints.max_width := 100;
|
||||
size_hints.min_height := AHeight;
|
||||
size_hints.max_height := 100;
|
||||
|
||||
XSetStandardProperties(fDisplay, fWindow, nil, nil, None, nil, 0, @size_hints);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtk1TrayIconHandle.PaintForm ()
|
||||
*
|
||||
* DESCRIPTION: Paint method of the Icon Window
|
||||
*
|
||||
* PARAMETERS: Sender of the event
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TGtk1TrayIconHandle.PaintForm(Sender: TObject);
|
||||
begin
|
||||
if fTrayIcon.ShowIcon then GtkForm.Canvas.Draw(0, 0, fTrayIcon.Icon);
|
||||
|
||||
if Assigned(fTrayIcon.OnPaint) then fTrayIcon.OnPaint(Self);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtkWSCustomTrayIcon.Hide ()
|
||||
*
|
||||
* DESCRIPTION: Hides the main tray icon of the program
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: True if sucessfull, otherwise False
|
||||
*
|
||||
*******************************************************************}
|
||||
class function TGtkWSCustomTrayIcon.Hide(const ATrayIcon: TCustomTrayIcon): Boolean;
|
||||
var
|
||||
TrayIconHandle: TGtk1TrayIconHandle;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
TrayIconHandle := TGtk1TrayIconHandle(ATrayIcon.Handle);
|
||||
|
||||
TrayIconHandle.GtkForm.Free;
|
||||
|
||||
TrayIconHandle.Free;
|
||||
|
||||
ATrayIcon.Handle := 0;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtkWSCustomTrayIcon.Show ()
|
||||
*
|
||||
* DESCRIPTION: Shows the main tray icon of the program
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: True if sucessfull, otherwise False
|
||||
*
|
||||
*******************************************************************}
|
||||
class function TGtkWSCustomTrayIcon.Show(const ATrayIcon: TCustomTrayIcon): Boolean;
|
||||
var
|
||||
TrayIconHandle: TGtk1TrayIconHandle;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
TrayIconHandle := TGtk1TrayIconHandle.Create;
|
||||
TrayIconHandle.fTrayIcon := ATrayIcon;
|
||||
|
||||
ATrayIcon.Handle := PtrInt(TrayIconHandle);
|
||||
|
||||
TrayIconHandle.CreateForm(0);
|
||||
|
||||
TrayIconHandle.SetEmbedded;
|
||||
|
||||
GTK_WIDGET_SET_FLAGS(PGtkWidget(TrayIconHandle.GtkForm.Handle),GTK_VISIBLE);
|
||||
GTK_WIDGET_SET_FLAGS(PGtkWidget(TrayIconHandle.GtkForm.Handle),GTK_MAPPED);
|
||||
|
||||
TrayIconHandle.GtkForm.Width := 22; //needed for gnome
|
||||
TrayIconHandle.GtkForm.Height := 22;
|
||||
TrayIconHandle.SetMinSize(ATrayIcon.Icon.Width, ATrayIcon.Icon.Height);
|
||||
|
||||
TrayIconHandle.GtkForm.OnMouseDown := ATrayIcon.OnMouseDown;
|
||||
TrayIconHandle.GtkForm.OnMouseMove := ATrayIcon.OnMouseMove;
|
||||
TrayIconHandle.GtkForm.OnMouseUp := ATrayIcon.OnMouseUp;
|
||||
TrayIconHandle.GtkForm.OnClick := ATrayIcon.OnClick;
|
||||
TrayIconHandle.GtkForm.OnDblClick := ATrayIcon.OnDblClick;
|
||||
TrayIconHandle.GtkForm.OnPaint := @TrayIconHandle.PaintForm;
|
||||
TrayIconHandle.GtkForm.PopupMenu := ATrayIcon.PopUpMenu;
|
||||
TrayIconHandle.GtkForm.Hint := ATrayIcon.Hint;
|
||||
|
||||
TrayIconHandle.fEmbedded := True;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtkWSCustomTrayIcon.InternalUpdate ()
|
||||
*
|
||||
* DESCRIPTION: Makes modifications to the Icon while running
|
||||
* i.e. without hiding it and showing again
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
class procedure TGtkWSCustomTrayIcon.InternalUpdate(const ATrayIcon: TCustomTrayIcon);
|
||||
var
|
||||
TrayIconHandle: TGtk1TrayIconHandle;
|
||||
begin
|
||||
TrayIconHandle := TGtk1TrayIconHandle(ATrayIcon.Handle);
|
||||
|
||||
if not Assigned(TrayIconHandle) then Exit;
|
||||
|
||||
if Assigned(TrayIconHandle.GtkForm) then
|
||||
TrayIconHandle.GtkForm.PopupMenu := ATrayIcon.PopUpMenu;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TGtkWSCustomTrayIcon.GetPosition ()
|
||||
*
|
||||
* DESCRIPTION: Returns the position of the tray icon on the display.
|
||||
* This function is utilized to show message boxes near
|
||||
* the icon
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURNS: Nothing
|
||||
*
|
||||
*******************************************************************}
|
||||
class function TGtkWSCustomTrayIcon.GetPosition(const ATrayIcon: TCustomTrayIcon): TPoint;
|
||||
begin
|
||||
Result.X := 0;
|
||||
Result.Y := 0;
|
||||
end;
|
||||
|
||||
|
@ -33,7 +33,7 @@ uses
|
||||
{$ELSE GTK2}
|
||||
gtk, gdk, glib, gtk1WSPrivate,
|
||||
{$ENDIF GTK2}
|
||||
GtkGlobals, GtkProc, GtkDef, ExtCtrls, Classes,
|
||||
GtkGlobals, GtkProc, GtkDef, ExtCtrls, Classes, Forms, SysUtils, Menus,
|
||||
WSExtCtrls, WSLCLClasses, gtkint, interfacebase;
|
||||
|
||||
type
|
||||
@ -211,8 +211,25 @@ type
|
||||
public
|
||||
end;
|
||||
|
||||
{ TGtkWSCustomTrayIcon }
|
||||
|
||||
{$IFDEF GTK1}
|
||||
TGtkWSCustomTrayIcon = class(TWSCustomTrayIcon)
|
||||
public
|
||||
class function Hide(const ATrayIcon: TCustomTrayIcon): Boolean; override;
|
||||
class function Show(const ATrayIcon: TCustomTrayIcon): Boolean; override;
|
||||
class procedure InternalUpdate(const ATrayIcon: TCustomTrayIcon); override;
|
||||
class function GetPosition(const ATrayIcon: TCustomTrayIcon): TPoint; override;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
{$IFDEF GTK1}
|
||||
uses
|
||||
x, xlib, xutil;
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
GtkPositionTypeMap: array[TTabPosition] of TGtkPositionType =
|
||||
(
|
||||
@ -624,6 +641,9 @@ begin
|
||||
UpdateWidgetStyleOfControl(AWinControl);
|
||||
end;
|
||||
|
||||
{$IFDEF GTK1}
|
||||
{$include gtk1trayicon.inc}
|
||||
{$ENDIF}
|
||||
|
||||
initialization
|
||||
|
||||
@ -654,6 +674,9 @@ initialization
|
||||
// RegisterWSComponent(TLabeledEdit, TGtkWSLabeledEdit);
|
||||
RegisterWSComponent(TCustomPanel, TGtkWSCustomPanel);
|
||||
// RegisterWSComponent(TPanel, TGtkWSPanel);
|
||||
{$IFDEF GTK1}
|
||||
RegisterWSComponent(TCustomTrayIcon, TGtkWSCustomTrayIcon);
|
||||
{$ENDIF}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
end.
|
||||
|
@ -1,4 +1,4 @@
|
||||
{%MainUnit win32wsextctrls.pp}
|
||||
{%MainUnit gtk2wsextctrls.pp}
|
||||
{
|
||||
gtk2trayicon.inc
|
||||
|
||||
@ -22,13 +22,6 @@
|
||||
|
||||
{ TGtk2WSCustomTrayIcon }
|
||||
|
||||
// if ShowIcon then GtkForm.Canvas.Draw(0, 0, Icon);
|
||||
|
||||
// if Assigned(OnPaint) then OnPaint(Self);
|
||||
|
||||
// Graphics, Classes, ExtCtrls, SysUtils, Forms, Controls, Dialogs, Menus,
|
||||
// x, xlib, xutil, gtk2, gdk2, gdk2x, glib2, gtkdef, gtkproc;
|
||||
|
||||
const
|
||||
SYSTEM_TRAY_REQUEST_DOCK = 0;
|
||||
SYSTEM_TRAY_BEGIN_MESSAGE = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user