Fixes AV in gtk2 TTrayIcon.InternalUpdate and adds a better handle mechanism to it

git-svn-id: trunk@16261 -
This commit is contained in:
sekelsenmat 2008-08-27 01:13:29 +00:00
parent a5edfe5a9b
commit 09225df31f

View File

@ -1,442 +1,438 @@
{%MainUnit gtk2wsextctrls.pp} {%MainUnit gtk2wsextctrls.pp}
{ {
gtk2trayicon.inc gtk2trayicon.inc
***************************************************************************** *****************************************************************************
* * * *
* See the file COPYING.modifiedLGPL.txt, included in this distribution, * * See the file COPYING.modifiedLGPL.txt, included in this distribution, *
* for details about the copyright. * * for details about the copyright. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* * * *
***************************************************************************** *****************************************************************************
Authors: Felipe Monteiro de Carvalho and Andrew Haines Authors: Felipe Monteiro de Carvalho and Andrew Haines
Special thanks for: Danny Milosavljevic and the Lazarus Team Special thanks for: Danny Milosavljevic and the Lazarus Team
Gtk2 specific code. Gtk2 specific code.
} }
{ TGtk2WSCustomTrayIcon } { TGtk2WSCustomTrayIcon }
const type
SYSTEM_TRAY_REQUEST_DOCK = 0; TGtk2WSTrayIconHandle = record
SYSTEM_TRAY_BEGIN_MESSAGE = 1; AImage: PGtkWidget;
SYSTEM_TRAY_CANCEL_MESSAGE = 2; end;
var PGtk2WSTrayIconHandle = ^TGtk2WSTrayIconHandle;
{$ifdef HasX}
fDisplay: PDisplay; const
fWindow: TWindow; SYSTEM_TRAY_REQUEST_DOCK = 0;
fScreen: PScreen; SYSTEM_TRAY_BEGIN_MESSAGE = 1;
fScreenID: longint; SYSTEM_TRAY_CANCEL_MESSAGE = 2;
fTrayParent: TWindow;
{$endif} var
{$ifdef HasX}
GtkForm: PGtkWidget; fDisplay: PDisplay;
Tips: PGtkTooltips; fWindow: TWindow;
fScreen: PScreen;
{$ifdef HasX} fScreenID: longint;
{******************************************************************* fTrayParent: TWindow;
* TempX11ErrorHandler () {$endif}
*
* DESCRIPTION: Temp ErrorHandler GtkForm: PGtkWidget;
* Tips: PGtkTooltips;
* PARAMETERS: ?
* {$ifdef HasX}
* RETURNS: ? {*******************************************************************
* * TempX11ErrorHandler ()
*******************************************************************} *
function TempX11ErrorHandler(Display:PDisplay; ErrorEv:PXErrorEvent):longint;cdecl; * DESCRIPTION: Temp ErrorHandler
begin *
WriteLn('Error: ' + IntToStr(ErrorEv^.error_code)); * PARAMETERS: ?
Result:=0; *
end; * RETURNS: ?
*
{******************************************************************* *******************************************************************}
* Send_Message () function TempX11ErrorHandler(Display:PDisplay; ErrorEv:PXErrorEvent):longint;cdecl;
* begin
* DESCRIPTION: Sends a message to the X client WriteLn('Error: ' + IntToStr(ErrorEv^.error_code));
* Result:=0;
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * Send_Message ()
*******************************************************************} *
function SendMessage(window: TWindow; msg: Integer; data1, data2, data3: Integer): boolean; * DESCRIPTION: Sends a message to the X client
var *
Ev: TXEvent; * PARAMETERS: None
begin *
FillChar(Ev, SizeOf(TXEvent), $0); * RETURNS: Nothing
*
ev.xclient._type := ClientMessage; *******************************************************************}
ev.xclient.window := window; function SendMessage(window: TWindow; msg: Integer; data1, data2, data3: Integer): boolean;
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False ); var
ev.xclient.format := 32; Ev: TXEvent;
ev.xclient.data.l[0] := CurrentTime; begin
ev.xclient.data.l[1] := msg; FillChar(Ev, SizeOf(TXEvent), $0);
ev.xclient.data.l[2] := data1;
ev.xclient.data.l[3] := data2; ev.xclient._type := ClientMessage;
ev.xclient.data.l[4] := data3; ev.xclient.window := window;
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False );
XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev); ev.xclient.format := 32;
XSync(fDisplay, False); ev.xclient.data.l[0] := CurrentTime;
Result := false;//(untrap_errors() = 0); ev.xclient.data.l[1] := msg;
end; ev.xclient.data.l[2] := data1;
ev.xclient.data.l[3] := data2;
{******************************************************************* ev.xclient.data.l[4] := data3;
* SetEmbedded ()
* XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev);
* DESCRIPTION: Docks the GtkPlug into the system tray XSync(fDisplay, False);
* Result := false;//(untrap_errors() = 0);
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * SetEmbedded ()
*******************************************************************} *
procedure SetEmbedded; * DESCRIPTION: Docks the GtkPlug into the system tray
var *
old_error: TXErrorHandler; * PARAMETERS: None
buf: array [0..32] of char; *
selection_atom : TAtom; * RETURNS: Nothing
begin *
old_error := XSetErrorHandler(@TempX11ErrorHandler); *******************************************************************}
procedure SetEmbedded;
xsync(fdisplay,true); var
buf := PChar('_NET_SYSTEM_TRAY_S' + IntToStr(fScreenID)); old_error: TXErrorHandler;
selection_atom := XInternAtom(fDisplay, buf, false); buf: array [0..32] of char;
XGrabServer(fDisplay); selection_atom : TAtom;
begin
fTrayParent := XGetSelectionOwner(fDisplay, selection_atom); old_error := XSetErrorHandler(@TempX11ErrorHandler);
if fTrayParent <> None then
begin xsync(fdisplay,true);
XSelectInput(fDisplay, fTrayParent, StructureNotifyMask); buf := PChar('_NET_SYSTEM_TRAY_S' + IntToStr(fScreenID));
end; selection_atom := XInternAtom(fDisplay, buf, false);
XGrabServer(fDisplay);
XUngrabServer(fDisplay);
XFlush(fDisplay); fTrayParent := XGetSelectionOwner(fDisplay, selection_atom);
if fTrayParent <> None then
if fTrayParent <> None then begin
SendMessage(fTrayParent, SYSTEM_TRAY_REQUEST_DOCK, fWindow, 0, 0); XSelectInput(fDisplay, fTrayParent, StructureNotifyMask);
end;
XSetErrorHandler(old_error);
end; XUngrabServer(fDisplay);
{$endif} XFlush(fDisplay);
{******************************************************************* if fTrayParent <> None then
* realize_cb () SendMessage(fTrayParent, SYSTEM_TRAY_REQUEST_DOCK, fWindow, 0, 0);
*
* DESCRIPTION: Callback function for the realize signal XSetErrorHandler(old_error);
* Sets the systray icon after the widget is realized end;
* {$endif}
* PARAMETERS: None
* {*******************************************************************
* RETURNS: Nothing * realize_cb ()
* *
*******************************************************************} * DESCRIPTION: Callback function for the realize signal
procedure realize_cb(widget: PGtkWidget; user_data: gpointer); cdecl; * Sets the systray icon after the widget is realized
begin *
{$ifdef HasGdk2X} * PARAMETERS: None
*
fDisplay := GDK_WINDOW_XDISPLAY(GtkForm^.window); * RETURNS: Nothing
fWindow := GDK_WINDOW_XWINDOW(GtkForm^.window); *
*******************************************************************}
{ Doesn´t work procedure realize_cb(widget: PGtkWidget; user_data: gpointer); cdecl;
begin
gdk_screen := gtk_widget_get_screen(GtkForm); {$ifdef HasGdk2X}
fScreen := GDK_SCREEN_XSCREEN(gdk_screen); // get the real screen}
fDisplay := GDK_WINDOW_XDISPLAY(GtkForm^.window);
fScreen := XDefaultScreenOfDisplay(fDisplay); fWindow := GDK_WINDOW_XWINDOW(GtkForm^.window);
fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
{ Doesn´t work
SetEmbedded;
{$endif} gdk_screen := gtk_widget_get_screen(GtkForm);
end; fScreen := GDK_SCREEN_XSCREEN(gdk_screen); // get the real screen}
{******************************************************************* fScreen := XDefaultScreenOfDisplay(fDisplay);
* button_release_cb () fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
*
* DESCRIPTION: Callback function for Mouse Click SetEmbedded;
* {$endif}
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * button_release_cb ()
*******************************************************************} *
function button_release_cb(widget: PGtkWidget; event: PGdkEventButton; * DESCRIPTION: Callback function for Mouse Click
user_data: gpointer): gboolean; cdecl; *
var * PARAMETERS: None
vwsTrayIcon: TCustomTrayIcon; *
begin * RETURNS: Nothing
vwsTrayIcon := TCustomTrayIcon(user_data); *
*******************************************************************}
Result := False; function button_release_cb(widget: PGtkWidget; event: PGdkEventButton;
user_data: gpointer): gboolean; cdecl;
case event^.button of var
1: vwsTrayIcon: TCustomTrayIcon;
begin begin
if Assigned(vwsTrayIcon.OnClick) then vwsTrayIcon.OnClick(vwsTrayIcon); vwsTrayIcon := TCustomTrayIcon(user_data);
if Assigned(vwsTrayIcon.OnMouseUp) then
vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbLeft, [], Round(event^.X), Round(event^.Y)); Result := False;
end;
case event^.button of
2: if Assigned(vwsTrayIcon.OnMouseUp) then 1:
vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbMiddle, [], Round(event^.X), Round(event^.Y)); begin
if Assigned(vwsTrayIcon.OnClick) then vwsTrayIcon.OnClick(vwsTrayIcon);
3: if Assigned(vwsTrayIcon.OnMouseUp) then
begin vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbLeft, [], Round(event^.X), Round(event^.Y));
if Assigned(vwsTrayIcon.OnMouseUp) then end;
vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
if Assigned(vwsTrayIcon.PopUpMenu) then 2: if Assigned(vwsTrayIcon.OnMouseUp) then
vwsTrayIcon.PopUpMenu.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y); vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbMiddle, [], Round(event^.X), Round(event^.Y));
end;
end; 3:
end; begin
if Assigned(vwsTrayIcon.OnMouseUp) then
{******************************************************************* vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
* button_press_cb () if Assigned(vwsTrayIcon.PopUpMenu) then
* vwsTrayIcon.PopUpMenu.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
* DESCRIPTION: Callback function for Mouse Click end;
* end;
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * button_press_cb ()
*******************************************************************} *
function button_press_cb(widget: PGtkWidget; event: PGdkEventButton; * DESCRIPTION: Callback function for Mouse Click
user_data: gpointer): gboolean; cdecl; *
var * PARAMETERS: None
vwsTrayIcon: TCustomTrayIcon; *
begin * RETURNS: Nothing
vwsTrayIcon := TCustomTrayIcon(user_data); *
*******************************************************************}
Result := False; function button_press_cb(widget: PGtkWidget; event: PGdkEventButton;
user_data: gpointer): gboolean; cdecl;
if (event^._type = GDK_2BUTTON_PRESS) and Assigned(vwsTrayIcon.OnDblClick) then var
vwsTrayIcon.OnDblClick(vwsTrayIcon) vwsTrayIcon: TCustomTrayIcon;
else begin
begin vwsTrayIcon := TCustomTrayIcon(user_data);
case event^.button of
1: if Assigned(vwsTrayIcon.OnMouseDown) then Result := False;
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbLeft, [], Round(event^.X), Round(event^.Y));
if (event^._type = GDK_2BUTTON_PRESS) and Assigned(vwsTrayIcon.OnDblClick) then
2: if Assigned(vwsTrayIcon.OnMouseDown) then vwsTrayIcon.OnDblClick(vwsTrayIcon)
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbMiddle, [], Round(event^.X), Round(event^.Y)); else
begin
3: if Assigned(vwsTrayIcon.OnMouseDown) then case event^.button of
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y)); 1: if Assigned(vwsTrayIcon.OnMouseDown) then
end; vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbLeft, [], Round(event^.X), Round(event^.Y));
end;
end; 2: if Assigned(vwsTrayIcon.OnMouseDown) then
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbMiddle, [], Round(event^.X), Round(event^.Y));
{*******************************************************************
* popup_cb () 3: if Assigned(vwsTrayIcon.OnMouseDown) then
* vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
* DESCRIPTION: Callback function for the popup menu end;
* end;
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * popup_cb ()
*******************************************************************} *
function popup_cb(widget: PGtkWidget; user_data: gpointer): Boolean; cdecl; * DESCRIPTION: Callback function for the popup menu
var *
vwsTrayIcon: TCustomTrayIcon; * PARAMETERS: None
begin *
vwsTrayIcon := TCustomTrayIcon(user_data); * RETURNS: Nothing
*
Result := True; *******************************************************************}
function popup_cb(widget: PGtkWidget; user_data: gpointer): Boolean; cdecl;
if Assigned(vwsTrayIcon.PopUpMenu) then var
vwsTrayIcon.PopUpMenu.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y); vwsTrayIcon: TCustomTrayIcon;
end; begin
vwsTrayIcon := TCustomTrayIcon(user_data);
{*******************************************************************
* motion_cb () Result := True;
*
* DESCRIPTION: Callback function for the OnMouseMove event if Assigned(vwsTrayIcon.PopUpMenu) then
* vwsTrayIcon.PopUpMenu.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * motion_cb ()
*******************************************************************} *
function motion_cb(widget: PGtkWidget; event: PGdkEventMotion; user_data: gpointer): Boolean; cdecl; * DESCRIPTION: Callback function for the OnMouseMove event
var *
vwsTrayIcon: TCustomTrayIcon; * PARAMETERS: None
begin *
vwsTrayIcon := TCustomTrayIcon(user_data); * RETURNS: Nothing
*
Result := False; *******************************************************************}
function motion_cb(widget: PGtkWidget; event: PGdkEventMotion; user_data: gpointer): Boolean; cdecl;
if Assigned(vwsTrayIcon.OnMouseMove) then var
vwsTrayIcon.OnMouseMove(vwsTrayIcon, [], Round(event^.X), Round(event^.Y)); vwsTrayIcon: TCustomTrayIcon;
end; begin
vwsTrayIcon := TCustomTrayIcon(user_data);
{*******************************************************************
* TGtk2WSCustomTrayIcon.Hide () Result := False;
*
* DESCRIPTION: Hides the main tray icon of the program if Assigned(vwsTrayIcon.OnMouseMove) then
* vwsTrayIcon.OnMouseMove(vwsTrayIcon, [], Round(event^.X), Round(event^.Y));
* PARAMETERS: None end;
*
* RETURNS: True if sucessfull, otherwise False {*******************************************************************
* * TGtk2WSCustomTrayIcon.Hide ()
*******************************************************************} *
class function TGtk2WSCustomTrayIcon.Hide(const ATrayIcon: TCustomTrayIcon): Boolean; * DESCRIPTION: Hides the main tray icon of the program
begin *
Result := False; * PARAMETERS: None
*
gtk_widget_destroy(GtkForm); * RETURNS: True if sucessfull, otherwise False
*
GtkForm := nil; *******************************************************************}
class function TGtk2WSCustomTrayIcon.Hide(const ATrayIcon: TCustomTrayIcon): Boolean;
g_object_unref(Tips); var
TrayHandle: PGtk2WSTrayIconHandle absolute ATrayIcon.Handle;
Tips := nil; begin
Result := False;
ATrayIcon.Handle := PtrInt(0);
gtk_widget_destroy(GtkForm);
Result := True;
end; GtkForm := nil;
{******************************************************************* g_object_unref(Tips);
* TGtk2WSCustomTrayIcon.Show ()
* Tips := nil;
* DESCRIPTION: Shows the main tray icon of the program
* { Free and nil the handle }
* PARAMETERS: None
* FreeMem(TrayHandle);
* RETURNS: True if sucessfull, otherwise False
* TrayHandle := nil;
*******************************************************************}
class function TGtk2WSCustomTrayIcon.Show(const ATrayIcon: TCustomTrayIcon): Boolean; Result := True;
var end;
AImage: PGtkWidget;
begin {*******************************************************************
Result := False; * TGtk2WSCustomTrayIcon.Show ()
*
{******************************************************************* * DESCRIPTION: Shows the main tray icon of the program
* Creates the GtkPlug *
*******************************************************************} * PARAMETERS: None
*
GtkForm := gtk_plug_new(0); * RETURNS: True if sucessfull, otherwise False
*
Tips := gtk_tooltips_new; *******************************************************************}
class function TGtk2WSCustomTrayIcon.Show(const ATrayIcon: TCustomTrayIcon): Boolean;
g_object_ref(Tips); var
TrayHandle: PGtk2WSTrayIconHandle absolute ATrayIcon.Handle;
gtk_object_sink(GTK_OBJECT(Tips)); begin
Result := False;
gtk_tooltips_set_tip(GTK_TOOLTIPS(Tips), GtkForm, PChar(ATrayIcon.Hint), '');
ATrayIcon.Handle := PtrInt(GetMem(SizeOf(TGtk2WSTrayIconHandle)));
{*******************************************************************
* Connects the signals {*******************************************************************
*******************************************************************} * Creates the GtkPlug
*******************************************************************}
gtk_widget_add_events(GtkForm, GDK_ALL_EVENTS_MASK);
GtkForm := gtk_plug_new(0);
g_signal_connect(GtkForm, 'realize', TGCallback(@realize_cb), ATrayIcon);
Tips := gtk_tooltips_new;
g_signal_connect(GtkForm, 'popup-menu', TGCallback(@popup_cb), ATrayIcon);
g_object_ref(Tips);
g_signal_connect(GtkForm, 'motion-notify-event', TGCallback(@motion_cb), ATrayIcon);
gtk_object_sink(GTK_OBJECT(Tips));
g_signal_connect(GtkForm, 'button-press-event', TGCallback(@button_press_cb), ATrayIcon);
gtk_tooltips_set_tip(GTK_TOOLTIPS(Tips), GtkForm, PChar(ATrayIcon.Hint), '');
g_signal_connect(GtkForm, 'button-release-event', TGCallback(@button_release_cb), ATrayIcon);
{*******************************************************************
{******************************************************************* * Connects the signals
* Draws the icon *******************************************************************}
*******************************************************************}
gtk_widget_add_events(GtkForm, GDK_ALL_EVENTS_MASK);
AImage := gtk_image_new_from_pixbuf(PGdkPixbuf(ATrayIcon.Icon.Handle));
g_signal_connect(GtkForm, 'realize', TGCallback(@realize_cb), ATrayIcon);
gtk_widget_show(AImage);
g_signal_connect(GtkForm, 'popup-menu', TGCallback(@popup_cb), ATrayIcon);
gtk_container_add(GTK_CONTAINER(GtkForm), AImage);
g_signal_connect(GtkForm, 'motion-notify-event', TGCallback(@motion_cb), ATrayIcon);
{*******************************************************************
* Now shows the GtkPlug g_signal_connect(GtkForm, 'button-press-event', TGCallback(@button_press_cb), ATrayIcon);
*******************************************************************}
g_signal_connect(GtkForm, 'button-release-event', TGCallback(@button_release_cb), ATrayIcon);
gtk_widget_show(GtkForm);
{*******************************************************************
{******************************************************************* * Draws the icon
* We don't use the GtkPlug for anything, but we reuse the image *******************************************************************}
* to update it in InternalUpdate, so we save the image
* as the handle TrayHandle^.AImage := gtk_image_new_from_pixbuf(PGdkPixbuf(ATrayIcon.Icon.Handle));
*******************************************************************}
ATrayIcon.Handle := PtrInt(AImage); gtk_widget_show(TrayHandle^.AImage);
Result := True; gtk_container_add(GTK_CONTAINER(GtkForm), TrayHandle^.AImage);
end;
{*******************************************************************
{******************************************************************* * Now shows the GtkPlug
* TGtk2WSCustomTrayIcon.InternalUpdate () *******************************************************************}
*
* DESCRIPTION: Makes modifications to the Icon while running gtk_widget_show(GtkForm);
* i.e. without hiding it and showing again
* Result := True;
* PARAMETERS: None end;
*
* RETURNS: Nothing {*******************************************************************
* * TGtk2WSCustomTrayIcon.InternalUpdate ()
*******************************************************************} *
class procedure TGtk2WSCustomTrayIcon.InternalUpdate(const ATrayIcon: TCustomTrayIcon); * DESCRIPTION: Makes modifications to the Icon while running
var * i.e. without hiding it and showing again
AImage: PGtkWidget; *
AMask: PGdkBitmap; * PARAMETERS: None
GDIObject: PgdiObject; *
begin * RETURNS: Nothing
// Updates the tooltips *
if Assigned(Tips) then gtk_tooltips_set_tip(GTK_TOOLTIPS(Tips), GtkForm, PChar(ATrayIcon.Hint), ''); *******************************************************************}
class procedure TGtk2WSCustomTrayIcon.InternalUpdate(const ATrayIcon: TCustomTrayIcon);
// Updates the icon var
TrayHandle: PGtk2WSTrayIconHandle absolute ATrayIcon.Handle;
AImage := PGtkWidget(ATrayIcon.Handle); begin
// Updates the tooltips
if AImage <> nil then if Assigned(Tips) then gtk_tooltips_set_tip(GTK_TOOLTIPS(Tips), GtkForm, PChar(ATrayIcon.Hint), '');
begin
GDIObject := PgdiObject(ATrayIcon.Icon.Handle); // Updates the icon
AMask := CreateGdkMaskBitmap( if (TrayHandle <> nil) and (TrayHandle^.AImage <> nil) then
GDIObject^.GDIPixmapObject.Mask, begin
GDIObject^.GDIBitmapObject); gtk_image_set_from_pixbuf(GTK_IMAGE(TrayHandle^.AImage), PGdkPixbuf(ATrayIcon.Icon.Handle));
end;
gtk_image_set_from_pixmap(GTK_IMAGE(AImage),GDIObject^.GDIPixmapObject.Image, AMask); end;
g_object_unref(AMask); {*******************************************************************
end; * TGtk2WSCustomTrayIcon.GetPosition ()
end; *
* DESCRIPTION: Returns the position of the tray icon on the display.
{******************************************************************* * This function is utilized to show message boxes near
* TGtk2WSCustomTrayIcon.GetPosition () * the icon
* *
* DESCRIPTION: Returns the position of the tray icon on the display. * PARAMETERS: None
* This function is utilized to show message boxes near *
* the icon * RETURNS: Nothing
* *
* PARAMETERS: None *******************************************************************}
* class function TGtk2WSCustomTrayIcon.GetPosition(const ATrayIcon: TCustomTrayIcon): TPoint;
* RETURNS: Nothing var
* WindowHandle: PGDKWindow;
*******************************************************************} begin
class function TGtk2WSCustomTrayIcon.GetPosition(const ATrayIcon: TCustomTrayIcon): TPoint; Result := Point(0, 0);
var
WindowHandle: PGDKWindow; if not Assigned(GtkForm) then Exit;
begin
Result := Point(0, 0); WindowHandle := GtkForm^.window;
if not Assigned(GtkForm) then Exit; if not Assigned(WindowHandle) then Exit;
WindowHandle := GtkForm^.window; gdk_window_get_origin(WindowHandle, @Result.X, @Result.Y);
end;
if not Assigned(WindowHandle) then Exit;
gdk_window_get_origin(WindowHandle, @Result.X, @Result.Y);
end;