mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-20 20:59:39 +01:00
various fixes for the TTrayIcon from Felipe
git-svn-id: trunk@8764 -
This commit is contained in:
parent
bb2b186050
commit
5ced41c831
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
This unit contains the SystrayIcon object and the TTrayIcon visual component.
|
This unit contains the SystrayIcon object and the TTrayIcon visual component.
|
||||||
|
|
||||||
Documentation for the component can be found here:
|
Documentation for the component can be found here:
|
||||||
|
|||||||
@ -47,6 +47,8 @@ type
|
|||||||
constructor Create; virtual;
|
constructor Create; virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure InternalUpdate; virtual; abstract;
|
procedure InternalUpdate; virtual; abstract;
|
||||||
|
function Hide: Boolean; virtual; abstract;
|
||||||
|
function Show: Boolean; virtual; abstract;
|
||||||
published
|
published
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -85,6 +87,8 @@ end;
|
|||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
destructor TCustomWidgetTrayIcon.Destroy;
|
destructor TCustomWidgetTrayIcon.Destroy;
|
||||||
begin
|
begin
|
||||||
|
Hide;
|
||||||
|
|
||||||
Icon.Free;
|
Icon.Free;
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -92,3 +96,4 @@ end;
|
|||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
Gtk2 specific code.
|
Gtk2 specific code.
|
||||||
}
|
}
|
||||||
unit wsgtk2trayicon;
|
unit wsgtk2trayicon;
|
||||||
@ -28,7 +30,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Graphics, Classes, ExtCtrls, SysUtils, Forms, Controls, Dialogs,
|
Graphics, Classes, ExtCtrls, SysUtils, Forms, Controls, Dialogs,
|
||||||
Menus, wscommontrayicon, x, xlib, xutil, gtk2, gdk2, gtkproc;
|
Menus, wscommontrayicon, x, xlib, xutil, gtk2, gdk2, gdk2x, glib2, gtkdef;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -36,28 +38,20 @@ type
|
|||||||
|
|
||||||
TWidgetTrayIcon = class(TCustomWidgetTrayIcon)
|
TWidgetTrayIcon = class(TCustomWidgetTrayIcon)
|
||||||
private
|
private
|
||||||
fDisplay: PDisplay;
|
|
||||||
fWindow: TWindow;
|
|
||||||
fScreen: PScreen;
|
|
||||||
fScreenID: longint;
|
|
||||||
fTrayParent: TWindow;
|
|
||||||
fOwner: TComponent;
|
fOwner: TComponent;
|
||||||
GtkForm: TForm;
|
|
||||||
fEmbedded: Boolean;
|
fEmbedded: Boolean;
|
||||||
fMsgCount: Integer;
|
fMsgCount: Integer;
|
||||||
procedure SetEmbedded;
|
Tips: PGtkTooltips;
|
||||||
function Send_Message(window: TWindow; msg: Integer; data1, data2, data3: Integer): boolean;
|
|
||||||
procedure SetMinSize(AWidth, AHeight: Integer);
|
|
||||||
procedure PaintForm(Sender: TObject);
|
|
||||||
procedure CreateForm(id: Integer);
|
procedure CreateForm(id: Integer);
|
||||||
procedure RemoveForm(id: Integer);
|
procedure RemoveForm(id: Integer);
|
||||||
function GetCanvas: TCanvas;
|
function GetCanvas: TCanvas;
|
||||||
protected
|
protected
|
||||||
public
|
public
|
||||||
function Hide: Boolean;
|
function Hide: Boolean; override;
|
||||||
function Show: Boolean;
|
function Show: Boolean; override;
|
||||||
property Canvas: TCanvas read GetCanvas;
|
property Canvas: TCanvas read GetCanvas;
|
||||||
procedure InternalUpdate; override;
|
procedure InternalUpdate; override;
|
||||||
|
procedure PaintForm(Sender: TObject);
|
||||||
published
|
published
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -68,15 +62,15 @@ const
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
type
|
uses WSTrayIcon;
|
||||||
PX11GdkDrawable = ^TX11GdkDrawable;
|
|
||||||
|
|
||||||
TX11GdkDrawable = record
|
var
|
||||||
parent_instance: TGdkWindow;
|
fDisplay: PDisplay;
|
||||||
wrapper: PGdkDrawable;
|
fWindow: TWindow;
|
||||||
colormap: PGdkColorMap;
|
fScreen: PScreen;
|
||||||
xid:x.TWindow;
|
fScreenID: longint;
|
||||||
end;
|
GtkForm: PGtkWidget;
|
||||||
|
fTrayParent: TWindow;
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
* TempX11ErrorHandler ()
|
* TempX11ErrorHandler ()
|
||||||
@ -93,47 +87,8 @@ begin
|
|||||||
WriteLn('Error: ' + IntToStr(ErrorEv^.error_code));
|
WriteLn('Error: ' + IntToStr(ErrorEv^.error_code));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TWidgetTrayIcon }
|
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
* TWidgetTrayIcon.SetEmbedded ()
|
* Send_Message ()
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* PARAMETERS: None
|
|
||||||
*
|
|
||||||
* RETURNS: Nothing
|
|
||||||
*
|
|
||||||
*******************************************************************}
|
|
||||||
procedure TWidgetTrayIcon.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;
|
|
||||||
|
|
||||||
{*******************************************************************
|
|
||||||
* TWidgetTrayIcon.Send_Message ()
|
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Sends a message to the X client
|
* DESCRIPTION: Sends a message to the X client
|
||||||
*
|
*
|
||||||
@ -142,11 +97,13 @@ end;
|
|||||||
* RETURNS: Nothing
|
* RETURNS: Nothing
|
||||||
*
|
*
|
||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
function TWidgetTrayIcon.Send_Message(window: TWindow; msg: Integer; data1, data2, data3: Integer): boolean;
|
function SendMessage(window: TWindow; msg: Integer; data1, data2, data3: Integer): boolean;
|
||||||
var
|
var
|
||||||
Ev: TXEvent;
|
Ev: TXEvent;
|
||||||
fmt: Integer;
|
fmt: Integer;
|
||||||
begin
|
begin
|
||||||
|
FillChar(Ev, SizeOf(TXEvent), $0);
|
||||||
|
|
||||||
ev.xclient._type := ClientMessage;
|
ev.xclient._type := ClientMessage;
|
||||||
ev.xclient.window := window;
|
ev.xclient.window := window;
|
||||||
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False );
|
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False );
|
||||||
@ -156,11 +113,185 @@ begin
|
|||||||
ev.xclient.data.l[2] := data1;
|
ev.xclient.data.l[2] := data1;
|
||||||
ev.xclient.data.l[3] := data2;
|
ev.xclient.data.l[3] := data2;
|
||||||
ev.xclient.data.l[4] := data3;
|
ev.xclient.data.l[4] := data3;
|
||||||
|
|
||||||
XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev);
|
XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev);
|
||||||
XSync(fDisplay, False);
|
XSync(fDisplay, False);
|
||||||
Result := false;//(untrap_errors() = 0);
|
Result := false;//(untrap_errors() = 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* SetEmbedded ()
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Docks the GtkPlug into the system tray
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURNS: Nothing
|
||||||
|
*
|
||||||
|
*******************************************************************}
|
||||||
|
procedure SetEmbedded;
|
||||||
|
var
|
||||||
|
old_error: TXErrorHandler;
|
||||||
|
buf: array [0..32] of char;
|
||||||
|
selection_atom : TAtom;
|
||||||
|
begin
|
||||||
|
old_error := XSetErrorHandler(@TempX11ErrorHandler);
|
||||||
|
|
||||||
|
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
|
||||||
|
SendMessage(fTrayParent, SYSTEM_TRAY_REQUEST_DOCK, fWindow, 0, 0);
|
||||||
|
|
||||||
|
XSetErrorHandler(old_error);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* realize_cb ()
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Callback function for the realize signal
|
||||||
|
* Sets the systray icon after the widget is realized
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURNS: Nothing
|
||||||
|
*
|
||||||
|
*******************************************************************}
|
||||||
|
procedure realize_cb(widget: PGtkWidget; user_data: gpointer); cdecl;
|
||||||
|
var
|
||||||
|
gdk_screen: PGdkScreen;
|
||||||
|
begin
|
||||||
|
fDisplay := GDK_WINDOW_XDISPLAY(GtkForm^.window);
|
||||||
|
fWindow := GDK_WINDOW_XWINDOW(GtkForm^.window);
|
||||||
|
|
||||||
|
{ Doesn´t work
|
||||||
|
|
||||||
|
gdk_screen := gtk_widget_get_screen(GtkForm);
|
||||||
|
fScreen := GDK_SCREEN_XSCREEN(gdk_screen); // get the real screen}
|
||||||
|
|
||||||
|
fScreen := XDefaultScreenOfDisplay(fDisplay);
|
||||||
|
fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
|
||||||
|
|
||||||
|
SetEmbedded;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* button_release_cb ()
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Callback function for Mouse Click
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURNS: Nothing
|
||||||
|
*
|
||||||
|
*******************************************************************}
|
||||||
|
function button_release_cb(widget: PGtkWidget; event: PGdkEventButton;
|
||||||
|
user_data: gpointer): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
case event^.button of
|
||||||
|
1:
|
||||||
|
begin
|
||||||
|
if Assigned(vwsTrayIcon.OnClick) then vwsTrayIcon.OnClick(vwsTrayIcon);
|
||||||
|
if Assigned(vwsTrayIcon.OnMouseUp) then
|
||||||
|
vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbLeft, [], Round(event^.X), Round(event^.Y));
|
||||||
|
end;
|
||||||
|
|
||||||
|
2: if Assigned(vwsTrayIcon.OnMouseUp) then
|
||||||
|
vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
|
||||||
|
|
||||||
|
3:
|
||||||
|
begin
|
||||||
|
if Assigned(vwsTrayIcon.OnMouseUp) then
|
||||||
|
vwsTrayIcon.OnMouseUp(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
|
||||||
|
if Assigned(vwsTrayIcon.PopUpMenu) then
|
||||||
|
vwsTrayIcon.PopUpMenu.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* button_press_cb ()
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Callback function for Mouse Click
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURNS: Nothing
|
||||||
|
*
|
||||||
|
*******************************************************************}
|
||||||
|
function button_press_cb(widget: PGtkWidget; event: PGdkEventButton;
|
||||||
|
user_data: gpointer): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
if (event^._type = GDK_2BUTTON_PRESS) and Assigned(vwsTrayIcon.OnDblClick) then
|
||||||
|
vwsTrayIcon.OnDblClick(vwsTrayIcon)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
case event^.button of
|
||||||
|
1: if Assigned(vwsTrayIcon.OnMouseUp) then
|
||||||
|
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbLeft, [], Round(event^.X), Round(event^.Y));
|
||||||
|
|
||||||
|
2: if Assigned(vwsTrayIcon.OnMouseUp) then
|
||||||
|
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
|
||||||
|
|
||||||
|
3: if Assigned(vwsTrayIcon.OnMouseUp) then
|
||||||
|
vwsTrayIcon.OnMouseDown(vwsTrayIcon, mbRight, [], Round(event^.X), Round(event^.Y));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* popup_cb ()
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Callback function for the popup menu
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURNS: Nothing
|
||||||
|
*
|
||||||
|
*******************************************************************}
|
||||||
|
function popup_cb(widget: PGtkWidget; user_data: gpointer): Boolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
if Assigned(vwsTrayIcon.PopUpMenu) then
|
||||||
|
vwsTrayIcon.PopUpMenu.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* motion_cb ()
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Callback function for the OnMouseMove event
|
||||||
|
*
|
||||||
|
* PARAMETERS: None
|
||||||
|
*
|
||||||
|
* RETURNS: Nothing
|
||||||
|
*
|
||||||
|
*******************************************************************}
|
||||||
|
function motion_cb(widget: PGtkWidget; event: PGdkEventMotion; user_data: gpointer): Boolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
if Assigned(vwsTrayIcon.OnMouseMove) then
|
||||||
|
vwsTrayIcon.OnMouseMove(vwsTrayIcon, [], Round(event^.X), Round(event^.Y));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWidgetTrayIcon }
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
* TWidgetTrayIcon.CreateForm ()
|
* TWidgetTrayIcon.CreateForm ()
|
||||||
*
|
*
|
||||||
@ -173,33 +304,59 @@ end;
|
|||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
procedure TWidgetTrayIcon.CreateForm(id: Integer);
|
procedure TWidgetTrayIcon.CreateForm(id: Integer);
|
||||||
var
|
var
|
||||||
Widget: PGtkWidget;
|
AImage: PGtkWidget;
|
||||||
|
GDIObject: PgdiObject;
|
||||||
begin
|
begin
|
||||||
GtkForm := TForm.Create(nil);
|
{*******************************************************************
|
||||||
|
* Creates the GtkPlug
|
||||||
|
*******************************************************************}
|
||||||
|
|
||||||
fEmbedded := False;
|
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
|
GtkForm := gtk_plug_new(0);
|
||||||
// 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;
|
Tips := gtk_tooltips_new;
|
||||||
|
|
||||||
fDisplay := GDK_DISPLAY;
|
g_object_ref(Tips);
|
||||||
// SHowMessage(IntToStr(Integer(fDisplay)));
|
|
||||||
Widget := PGtkWidget(GtkForm.Handle);
|
gtk_object_sink(GTK_OBJECT(Tips));
|
||||||
fWindow := PX11GdkDrawable(PGdkWindowObject(Widget^.window)^.impl)^.xid;
|
|
||||||
|
gtk_tooltips_set_tip(GTK_TOOLTIPS(Tips), GtkForm, PChar(Hint), '');
|
||||||
|
|
||||||
fScreen := XDefaultScreenOfDisplay(fDisplay); // get the screen
|
{*******************************************************************
|
||||||
fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
|
* Connects the signals
|
||||||
|
*******************************************************************}
|
||||||
|
|
||||||
|
gtk_widget_add_events(GtkForm, GDK_ALL_EVENTS_MASK);
|
||||||
|
|
||||||
|
g_signal_connect(GtkForm, 'realize', TGCallback(@realize_cb), nil);
|
||||||
|
|
||||||
|
g_signal_connect(GtkForm, 'popup-menu', TGCallback(@popup_cb), nil);
|
||||||
|
|
||||||
|
g_signal_connect(GtkForm, 'motion-notify-event', TGCallback(@motion_cb), nil);
|
||||||
|
|
||||||
|
g_signal_connect(GtkForm, 'button-press-event', TGCallback(@button_press_cb), nil);
|
||||||
|
|
||||||
|
g_signal_connect(GtkForm, 'button-release-event', TGCallback(@button_release_cb), nil);
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* Draws the icon
|
||||||
|
*******************************************************************}
|
||||||
|
|
||||||
|
GDIObject := PgdiObject(Icon.Handle);
|
||||||
|
|
||||||
|
AImage := gtk_image_new_from_pixmap(GDIObject^.GDIPixmapObject,
|
||||||
|
GDIObject^.GDIBitmapMaskObject);
|
||||||
|
|
||||||
|
gtk_widget_show(AImage);
|
||||||
|
|
||||||
|
gtk_container_add(GTK_CONTAINER(GtkForm), AImage);
|
||||||
|
|
||||||
|
{*******************************************************************
|
||||||
|
* Now shows the GtkPlug
|
||||||
|
*******************************************************************}
|
||||||
|
|
||||||
|
gtk_widget_show(GtkForm);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
@ -214,7 +371,13 @@ end;
|
|||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
procedure TWidgetTrayIcon.RemoveForm(id: Integer);
|
procedure TWidgetTrayIcon.RemoveForm(id: Integer);
|
||||||
begin
|
begin
|
||||||
GtkForm.Free;
|
gtk_widget_destroy(GtkForm);
|
||||||
|
|
||||||
|
GtkForm := nil;
|
||||||
|
|
||||||
|
g_object_unref(Tips);
|
||||||
|
|
||||||
|
Tips := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
@ -229,7 +392,7 @@ end;
|
|||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
function TWidgetTrayIcon.GetCanvas: TCanvas;
|
function TWidgetTrayIcon.GetCanvas: TCanvas;
|
||||||
begin
|
begin
|
||||||
Result := GtkForm.Canvas;
|
Result := Icon.Canvas;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
@ -273,22 +436,6 @@ begin
|
|||||||
|
|
||||||
CreateForm(0);
|
CreateForm(0);
|
||||||
|
|
||||||
SetEmbedded;
|
|
||||||
|
|
||||||
GTK_WIDGET_SET_FLAGS(PGtkWidget(GtkForm.Handle),GTK_VISIBLE);
|
|
||||||
GTK_WIDGET_SET_FLAGS(PGtkWidget(GtkForm.Handle),GTK_MAPPED);
|
|
||||||
|
|
||||||
GtkForm.Width := 22; //needed for gnome
|
|
||||||
GtkForm.Height := 22;
|
|
||||||
SetMinSize(Icon.Width, Icon.Height);
|
|
||||||
|
|
||||||
GtkForm.OnMouseDown := Self.OnMouseDown;
|
|
||||||
GtkForm.OnMouseMove := Self.OnMouseMove;
|
|
||||||
GtkForm.OnMouseUp := Self.OnMouseUp;
|
|
||||||
GtkForm.OnClick := Self.OnClick;
|
|
||||||
GtkForm.OnPaint := PaintForm;
|
|
||||||
GtkForm.PopupMenu := Self.PopUpMenu;
|
|
||||||
|
|
||||||
fEmbedded := True;
|
fEmbedded := True;
|
||||||
|
|
||||||
vVisible := True;
|
vVisible := True;
|
||||||
@ -296,28 +443,6 @@ begin
|
|||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*******************************************************************
|
|
||||||
* TWidgetTrayIcon.SetMinSize ()
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Attemps to avoid problems on Gnome
|
|
||||||
*
|
|
||||||
* PARAMETERS:
|
|
||||||
*
|
|
||||||
* RETURNS: Nothing
|
|
||||||
*
|
|
||||||
*******************************************************************}
|
|
||||||
procedure TWidgetTrayIcon.SetMinSize(AWidth, AHeight: Integer);
|
|
||||||
var
|
|
||||||
size_hints: TXSizeHints;
|
|
||||||
begin
|
|
||||||
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;
|
|
||||||
|
|
||||||
{*******************************************************************
|
{*******************************************************************
|
||||||
* TWidgetTrayIcon.PaintForm ()
|
* TWidgetTrayIcon.PaintForm ()
|
||||||
*
|
*
|
||||||
@ -330,7 +455,7 @@ end;
|
|||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
procedure TWidgetTrayIcon.PaintForm(Sender: TObject);
|
procedure TWidgetTrayIcon.PaintForm(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if ShowIcon then GtkForm.Canvas.Draw(0, 0, Icon);
|
// if ShowIcon then GtkForm.Canvas.Draw(0, 0, Icon);
|
||||||
|
|
||||||
if Assigned(OnPaint) then OnPaint(Self);
|
if Assigned(OnPaint) then OnPaint(Self);
|
||||||
end;
|
end;
|
||||||
@ -348,7 +473,7 @@ end;
|
|||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
procedure TWidgetTrayIcon.InternalUpdate;
|
procedure TWidgetTrayIcon.InternalUpdate;
|
||||||
begin
|
begin
|
||||||
if Assigned(GtkForm) then GtkForm.PopupMenu := Self.PopUpMenu;
|
if Assigned(Tips) then gtk_tooltips_set_tip(GTK_TOOLTIPS(Tips), GtkForm, PChar(Hint), '');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
Gtk1 specific code. Works on gnome also.
|
Gtk1 specific code. Works on gnome also.
|
||||||
}
|
}
|
||||||
unit wsgtktrayicon;
|
unit wsgtktrayicon;
|
||||||
@ -52,8 +54,8 @@ type
|
|||||||
function GetCanvas: TCanvas;
|
function GetCanvas: TCanvas;
|
||||||
protected
|
protected
|
||||||
public
|
public
|
||||||
function Hide: Boolean;
|
function Hide: Boolean; override;
|
||||||
function Show: Boolean;
|
function Show: Boolean; override;
|
||||||
property Canvas: TCanvas read GetCanvas;
|
property Canvas: TCanvas read GetCanvas;
|
||||||
procedure InternalUpdate; override;
|
procedure InternalUpdate; override;
|
||||||
published
|
published
|
||||||
@ -127,6 +129,8 @@ var
|
|||||||
Ev: TXEvent;
|
Ev: TXEvent;
|
||||||
fmt: Integer;
|
fmt: Integer;
|
||||||
begin
|
begin
|
||||||
|
FillChar(Ev, SizeOf(TXEvent), $0);
|
||||||
|
|
||||||
ev.xclient._type := ClientMessage;
|
ev.xclient._type := ClientMessage;
|
||||||
ev.xclient.window := window;
|
ev.xclient.window := window;
|
||||||
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False );
|
ev.xclient.message_type := XInternAtom (fDisplay, '_NET_SYSTEM_TRAY_OPCODE', False );
|
||||||
@ -136,6 +140,7 @@ begin
|
|||||||
ev.xclient.data.l[2] := data1;
|
ev.xclient.data.l[2] := data1;
|
||||||
ev.xclient.data.l[3] := data2;
|
ev.xclient.data.l[3] := data2;
|
||||||
ev.xclient.data.l[4] := data3;
|
ev.xclient.data.l[4] := data3;
|
||||||
|
|
||||||
XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev);
|
XSendEvent(fDisplay, fTrayParent, False, NoEventMask, @ev);
|
||||||
XSync(fDisplay, False);
|
XSync(fDisplay, False);
|
||||||
Result := false;//(untrap_errors() = 0);
|
Result := false;//(untrap_errors() = 0);
|
||||||
@ -172,7 +177,6 @@ begin
|
|||||||
Application.ProcessMessages;
|
Application.ProcessMessages;
|
||||||
|
|
||||||
fDisplay := GDK_WINDOW_XDISPLAY(Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
fDisplay := GDK_WINDOW_XDISPLAY(Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
||||||
// SHowMessage(IntToStr(Integer(fDisplay)));
|
|
||||||
fWindow := GDK_WINDOW_XWINDOW (Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
fWindow := GDK_WINDOW_XWINDOW (Pointer(PGtkWidget(GtkForm.Handle)^.window));
|
||||||
fScreen := XDefaultScreenOfDisplay(fDisplay); // get the screen
|
fScreen := XDefaultScreenOfDisplay(fDisplay); // get the screen
|
||||||
fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
|
fScreenID := XScreenNumberOfScreen(fScreen); // and it's number
|
||||||
@ -287,11 +291,14 @@ procedure TWidgetTrayIcon.SetMinSize(AWidth, AHeight: Integer);
|
|||||||
var
|
var
|
||||||
size_hints: TXSizeHints;
|
size_hints: TXSizeHints;
|
||||||
begin
|
begin
|
||||||
|
FillChar(size_hints, SizeOf(TXSizeHints), $0);
|
||||||
|
|
||||||
size_hints.flags := PSize or PMinSize or PMaxSize;
|
size_hints.flags := PSize or PMinSize or PMaxSize;
|
||||||
size_hints.min_width := AWidth;
|
size_hints.min_width := AWidth;
|
||||||
size_hints.max_width := 100;
|
size_hints.max_width := 100;
|
||||||
size_hints.min_height := AHeight;
|
size_hints.min_height := AHeight;
|
||||||
size_hints.max_height := 100;
|
size_hints.max_height := 100;
|
||||||
|
|
||||||
XSetStandardProperties(fDisplay, fWindow, nil, nil, None, nil, 0, @size_hints);
|
XSetStandardProperties(fDisplay, fWindow, nil, nil, None, nil, 0, @size_hints);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -330,3 +337,4 @@ end;
|
|||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
This unit calls the appropriate widgetset code.
|
This unit calls the appropriate widgetset code.
|
||||||
}
|
}
|
||||||
unit wstrayicon;
|
unit wstrayicon;
|
||||||
@ -28,23 +30,33 @@ interface
|
|||||||
* Compatibility code for Delphi for Windows.
|
* Compatibility code for Delphi for Windows.
|
||||||
*******************************************************************}
|
*******************************************************************}
|
||||||
{$ifndef FPC}
|
{$ifndef FPC}
|
||||||
{$define LCLWin32}
|
{$define Win32}
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef LCLWin32}
|
|
||||||
|
{$ifdef Win32}
|
||||||
|
|
||||||
wswin32trayicon,
|
wswin32trayicon,
|
||||||
|
|
||||||
{$endif}
|
{$endif}
|
||||||
{$ifdef LCLGtk}
|
{$ifdef UNIX}
|
||||||
wsgtktrayicon,
|
|
||||||
{$endif}
|
{$ifdef LCLGtk}
|
||||||
{$ifdef LCLGnome}
|
wsgtktrayicon,
|
||||||
wsgtktrayicon,
|
{$endif}
|
||||||
{$endif}
|
|
||||||
{$ifdef LCLGtk2}
|
{$ifdef LCLGnome}
|
||||||
wsgtk2trayicon,
|
wsgtktrayicon,
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef LCLGtk2}
|
||||||
|
wsgtk2trayicon,
|
||||||
|
{$endif}
|
||||||
|
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
Classes, SysUtils;
|
Classes, SysUtils;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -76,3 +88,4 @@ finalization
|
|||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
Win32 specific code.
|
Win32 specific code.
|
||||||
}
|
}
|
||||||
unit wswin32trayicon;
|
unit wswin32trayicon;
|
||||||
@ -39,8 +41,8 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function Hide: Boolean;
|
function Hide: Boolean; override;
|
||||||
function Show: Boolean;
|
function Show: Boolean; override;
|
||||||
property Canvas: TCanvas read GetCanvas;
|
property Canvas: TCanvas read GetCanvas;
|
||||||
procedure InternalUpdate; override;
|
procedure InternalUpdate; override;
|
||||||
published
|
published
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user