mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-16 03:40:36 +01:00
Patch from Giuliano: Fixes compilation, adds a new smart painting for X11, improves trayicon for X11
git-svn-id: trunk@36721 -
This commit is contained in:
parent
34e6e9ce12
commit
c74dcfc14e
@ -29,6 +29,10 @@ type
|
||||
Colormap: TColormap;
|
||||
GC: TGC;
|
||||
ColorDepth: Byte;
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
Valid: Boolean;
|
||||
Moved: Boolean;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
{$ifdef CD_X11_UseNewTimer}
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
{$define CD_X11_NewNativePaint}
|
||||
{$define CD_X11_UseLCL_MainLoop}
|
||||
{$define CD_X11_UseNewTimer}
|
||||
{$define CD_X11_SmartPaint}
|
||||
|
||||
// ==================
|
||||
// X11 experimental options
|
||||
@ -58,7 +59,7 @@
|
||||
// To be able to use TThreads, UseCThreads must be defined in the application!
|
||||
{ $ifdef UseCTthreads}
|
||||
{$ifdef CD_X11_UseNewTimer}
|
||||
{ $define TimerUseCThreads}
|
||||
{.$define TimerUseCThreads}
|
||||
{$endif}
|
||||
{ $endif}
|
||||
{$endif}
|
||||
@ -73,5 +74,6 @@
|
||||
{.$define VerboseCDBitmap}
|
||||
{.$define VerboseCDForms}
|
||||
{.$define VerboseCDX11WinAPI}
|
||||
{.$define VerboseCDEvents}
|
||||
{.$define VerboseCDAccessibility}
|
||||
|
||||
|
||||
@ -29,13 +29,15 @@ interface
|
||||
|
||||
uses
|
||||
// RTL
|
||||
Classes, SysUtils, Math,
|
||||
// for CD_Cocoa Types needs to be after the platform-specif units or else Mac
|
||||
// will catch MacOSAll.Rect/Size/Point
|
||||
{$ifndef CD_Cocoa}Types,{$endif}Classes, SysUtils, Math,
|
||||
fpimage, fpcanvas, fpimgcanv, ctypes, dateutils,
|
||||
// XML
|
||||
XMLRead, Dom,
|
||||
// Platform specific
|
||||
{$ifdef CD_Windows}Windows, customdrawn_WinProc,{$endif}
|
||||
{$ifdef CD_Cocoa}MacOSAll, CocoaAll, customdrawn_cocoaproc, CocoaGDIObjects,{$endif}
|
||||
{$ifdef CD_Cocoa}MacOSAll, CocoaAll, customdrawn_cocoaproc, CocoaGDIObjects,Types,{$endif}
|
||||
{$ifdef CD_X11}X, XLib, XUtil, BaseUnix, customdrawn_x11proc,{$ifdef CD_UseNativeText}xft, fontconfig,{$endif}{$endif}
|
||||
{$ifdef CD_Android}
|
||||
customdrawn_androidproc, jni, bitmap, log, keycodes,
|
||||
@ -47,8 +49,6 @@ uses
|
||||
// LazFreeType
|
||||
LazFreeTypeIntfDrawer, LazFreeType, EasyLazFreeType, IniFiles,
|
||||
{$endif}
|
||||
// Types needs to be after the platform-specif units or else Mac will catch MacOSAll.Rect/Size/Point
|
||||
Types,
|
||||
// Widgetset
|
||||
customdrawnproc,
|
||||
// LCL
|
||||
@ -92,6 +92,9 @@ type
|
||||
function applicationShouldTerminate(sender: NSApplication): NSApplicationTerminateReply; message 'applicationShouldTerminate:';
|
||||
end;
|
||||
{$endif}
|
||||
{$ifdef CD_X11}
|
||||
// Just in case...
|
||||
{$endif}
|
||||
|
||||
// Return true to disable the form background drawing
|
||||
TDisableFormBackgroundDrawingProc = function (AForm: TCustomForm): Boolean of object;
|
||||
@ -148,6 +151,8 @@ type
|
||||
{$ifdef CD_X11}
|
||||
FDisplayName: string;
|
||||
FDisplay: PDisplay;
|
||||
FScreen: longint;
|
||||
FVisual: TVisual; // Visual from X11
|
||||
|
||||
LeaderWindow: X.TWindow;
|
||||
ClientLeaderAtom: TAtom;
|
||||
|
||||
@ -42,6 +42,10 @@ begin
|
||||
if XWindowList.Strings[I] <> 'Paint' then begin
|
||||
XWindowList.Strings[I] := 'Paint';
|
||||
Result:= True;
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
AWindowInfo.Valid:= True;
|
||||
AWindowInfo.Moved:= False;
|
||||
{$endif}
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
@ -152,6 +156,10 @@ end;
|
||||
procedure TCDWidgetSet.AppInit(var ScreenInfo: TScreenInfo);
|
||||
var
|
||||
ClassHint: PXClassHint;
|
||||
DW,DH,DWMM,DHMM: culong;
|
||||
I: Integer;
|
||||
APVisual: PVisual;
|
||||
|
||||
begin
|
||||
{$ifdef Verbose_CDWS}
|
||||
// DebugLn('TCDWidgetSet.AppInit');
|
||||
@ -171,6 +179,8 @@ begin
|
||||
|
||||
if not Assigned(FDisplay) then
|
||||
raise Exception.Create('[TCDWidgetSet.AppInit] XOpenDisplay failed');
|
||||
// if we have a Display then we should have a Screen too
|
||||
FScreen:= XDefaultScreen(FDisplay);
|
||||
|
||||
// Keyboard initialization
|
||||
|
||||
@ -181,12 +191,47 @@ begin
|
||||
if InputContext = nil then DebugLn('[TCDWidgetSet.BackendInit] Failed to initialize the Keyboard handling!');
|
||||
|
||||
// Initialize ScreenInfo
|
||||
ScreenInfo.PixelsPerInchX:= 96;
|
||||
ScreenInfo.PixelsPerInchY:= 96;
|
||||
|
||||
// Screen Metrics
|
||||
DW:= XDisplayWidth(FDisplay,FScreen);
|
||||
DWMM:= XDisplayWidthMM(FDisplay,FScreen);
|
||||
ScreenInfo.PixelsPerInchX:= round(float(DW)/(DWMM/25.4));
|
||||
DH:= XDisplayHeight(FDisplay,FScreen);
|
||||
DHMM:=XDisplayHeightMM(FDisplay,FScreen);
|
||||
ScreenInfo.PixelsPerInchY:= round(float(DH)/(DHMM/25.4));
|
||||
// Color Depth
|
||||
ScreenInfo.ColorDepth:= XDefaultDepth(FDisplay,FScreen);
|
||||
ScreenInfo.Initialized:= True;
|
||||
|
||||
// ToDo: Actually check which format it is at
|
||||
ScreenFormat := clfBGR24;
|
||||
// Pixmap Format
|
||||
APVisual:= XDefaultVisual(FDisplay,FScreen);
|
||||
FVisual:= APVisual^;
|
||||
if (ScreenInfo.ColorDepth = 16) then ScreenFormat:= clfRGB16_R5G6B5
|
||||
else if (ScreenInfo.ColorDepth = 24) then begin
|
||||
if (FVisual.blue_mask = $FF) and
|
||||
(FVisual.green_mask = $FF00) and
|
||||
(FVisual.red_mask = $FF0000) then
|
||||
ScreenFormat:= clfBGR24
|
||||
else if (FVisual.red_mask = $FF) and
|
||||
(FVisual.green_mask = $FF00) and
|
||||
(FVisual.blue_mask = $FF0000) then
|
||||
ScreenFormat:= clfRGB24;
|
||||
end
|
||||
else if (ScreenInfo.ColorDepth = 32) then begin
|
||||
if (FVisual.blue_mask = $FF) and
|
||||
(FVisual.green_mask = $FF00) and
|
||||
(FVisual.red_mask = $FF0000) then
|
||||
ScreenFormat:= clfBGRA32
|
||||
else if (FVisual.red_mask = $FF) and
|
||||
(FVisual.green_mask = $FF00) and
|
||||
(FVisual.blue_mask = $FF0000) then
|
||||
ScreenFormat:= clfRGBA32
|
||||
else if (FVisual.red_mask = $FF00) and
|
||||
(FVisual.green_mask = $FF0000) and
|
||||
(FVisual.blue_mask = $FF000000) then
|
||||
ScreenFormat:= clfARGB32;
|
||||
end;
|
||||
//ScreenFormat := clfBGR24;
|
||||
|
||||
//if (not (woX11SkipWMHints in WindowOptions)) and (woWindow in WindowOptions) then
|
||||
//begin
|
||||
@ -440,7 +485,15 @@ begin
|
||||
// http://tronche.com/gui/x/xlib/events/exposure/expose.html
|
||||
if XEvent.xexpose.count = 0 then
|
||||
begin
|
||||
TCDWSCustomForm.EvPaint(WindowEntry, CurWindowInfo);
|
||||
{$ifdef VerboseCDEvents}
|
||||
DebugLn(Format('X11 event X.Expose - Window %d',[CurWindowInfo.Window]));
|
||||
{$endif}
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
if CurWindowInfo.Valid then
|
||||
TCDWSCustomForm.EvPaintEx(WindowEntry, CurWindowInfo)
|
||||
else
|
||||
{$endif}
|
||||
TCDWSCustomForm.EvPaint(WindowEntry, CurWindowInfo);
|
||||
end;
|
||||
end;
|
||||
X.ConfigureNotify:
|
||||
@ -450,12 +503,13 @@ begin
|
||||
X.ClientMessage:
|
||||
begin
|
||||
if XClientEvent.message_type = CDWidgetSet.FWMPaint then begin
|
||||
{$ifdef VerboseCDEvents}
|
||||
DebugLn(Format('X11 event WM_PAINT - Window %d',[CurWindowInfo.Window]));
|
||||
{$endif}
|
||||
{$IFDEF VerboseCDPaintProfiler}
|
||||
lMessageTime:= DateTimeToMilliseconds(Now)-XClientEvent.data.l[1];
|
||||
DebugLn(Format('X11 event WM_PAINT - Window %d, Delay %d ms',[CurWindowInfo.Window,lMessageTime]));
|
||||
DebugLn(Format('CD_X11 event WM_PAINT - Window %d, Delay %d ms',[CurWindowInfo.Window,lMessageTime]));
|
||||
{$else}
|
||||
{$ifdef VerboseCDEvents}
|
||||
DebugLn(Format('CD_X11 event WM_PAINT - Window %d',[CurWindowInfo.Window]));
|
||||
{$endif}
|
||||
{$ENDIF}
|
||||
TCDWSCustomForm.EvPaintEx(WindowEntry, CurWindowInfo);
|
||||
WindowUpdated(CurWindowInfo.Window);
|
||||
|
||||
@ -21,6 +21,7 @@ type
|
||||
procedure PaintForm(Sender: TObject);
|
||||
function Send_Message(window: TWindow; msg: Integer;data1, data2,data3: Integer): boolean;
|
||||
public
|
||||
constructor create;
|
||||
destructor Destroy; override;
|
||||
procedure CreateForm(id: Integer);
|
||||
function GetPosition: TPoint;
|
||||
@ -149,6 +150,11 @@ begin
|
||||
Result := false;//(untrap_errors() = 0);
|
||||
end;
|
||||
|
||||
constructor TX11TrayIconHandle.create;
|
||||
begin
|
||||
inherited create;
|
||||
end;
|
||||
|
||||
function TX11TrayIconHandle.TrayParent(UseCachedValue: Boolean = True): TWindow;
|
||||
var
|
||||
buf: array[0..32] of char;
|
||||
@ -157,15 +163,12 @@ begin
|
||||
if (fTrayParent <> 0) and UseCachedValue then
|
||||
Exit(fTrayParent);
|
||||
fDisplay := CDWidgetset.FDisplay;
|
||||
fScreenID := DefaultScreen(CDWidgetSet.FDisplay);
|
||||
XGrabServer(fDisplay);
|
||||
fScreenID := CDWidgetSet.FScreen;
|
||||
|
||||
buf := PChar('_NET_SYSTEM_TRAY_S' + IntToStr(fScreenID));
|
||||
selection_atom := XInternAtom(fDisplay, buf, false);
|
||||
fTrayParent := XGetSelectionOwner(fDisplay, selection_atom);
|
||||
|
||||
XUngrabServer(fDisplay);
|
||||
|
||||
Result := fTrayParent;
|
||||
end;
|
||||
|
||||
@ -208,10 +211,7 @@ begin
|
||||
Sleep(80);
|
||||
xsync(fdisplay,true);
|
||||
|
||||
XGrabServer(fDisplay);
|
||||
XSelectInput(fDisplay, TrayParent, StructureNotifyMask);
|
||||
XUngrabServer(fDisplay);
|
||||
XFlush(fDisplay);
|
||||
|
||||
//fWindow := GDK_WINDOW_XWINDOW (Pointer(PGtkWidget(plug)^.window));
|
||||
|
||||
@ -251,7 +251,6 @@ begin
|
||||
gtk_signal_connect_object(G_OBJECT(drawingarea), 'motion-notify-event', TGtkSignalFunc(@TGtk1TrayIconHandle.NotifyMouseMove), G_OBJECT(Self));
|
||||
gtk_signal_connect_object(G_OBJECT(drawingarea), 'button-press-event', TGtkSignalFunc(@TGtk1TrayIconHandle.NotifyMouseDown), G_OBJECT(Self));
|
||||
gtk_signal_connect_object(G_OBJECT(drawingarea), 'button-release-event', TGtkSignalFunc(@TGtk1TrayIconHandle.NotifyMouseUp), G_OBJECT(Self));}
|
||||
//
|
||||
|
||||
fEmbedded := False;
|
||||
GetCanvas;
|
||||
|
||||
@ -209,6 +209,10 @@ begin
|
||||
|
||||
GCValues.graphics_exposures := 0;
|
||||
AWindowInfo.GC := XCreateGC(CDWidgetSet.FDisplay, AWindowInfo.Window, GCGraphicsExposures, @GCValues);
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
AWindowInfo.Valid:= False; // Need Paint
|
||||
AWindowInfo.Moved:= False; // And not move
|
||||
{$endif}
|
||||
// if not Assigned(GC) then
|
||||
// raise EX11Error.Create(SGCCreationFailed);
|
||||
|
||||
@ -665,9 +669,18 @@ begin
|
||||
TrueColor = 4;
|
||||
DirectColor = 5;}
|
||||
{$ENDIF}
|
||||
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
if AWindowInfo.InvalidateRequestedInAnyControl then AWindowInfo.Valid:= False;
|
||||
if (not AWindowInfo.Moved) or (not AWindowInfo.Valid) then begin // we're here just because a Move. We don't need to repaint
|
||||
UpdateControlLazImageAndCanvas(AWindowInfo.Image, AWindowInfo.Canvas, lWidth, lHeight, clfBGR24);
|
||||
RenderForm(AWindowInfo.Image, AWindowInfo.Canvas, TCustomForm(AWinControl));
|
||||
end;
|
||||
{$else}
|
||||
UpdateControlLazImageAndCanvas(AWindowInfo.Image, AWindowInfo.Canvas, lWidth, lHeight, clfBGR24);
|
||||
|
||||
RenderForm(AWindowInfo.Image, AWindowInfo.Canvas, TCustomForm(AWinControl));
|
||||
{$endif}
|
||||
|
||||
{$IFDEF VerboseCDPaintProfiler}
|
||||
lCDTimeEnd := NowUTC();
|
||||
@ -732,11 +745,17 @@ begin
|
||||
// Move event
|
||||
if (Event.x <> AWinControl.Left) or (Event.y <> AWinControl.Top) then
|
||||
begin
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
AWindowInfo.Moved:= True; // doesn't need full painting
|
||||
{$endif}
|
||||
LCLSendMoveMsg(AWinControl, Event.x, Event.y);
|
||||
end;
|
||||
// Size event
|
||||
if (Event.Width <> AWinControl.Width) or (Event.Height <> AWinControl.Height) then
|
||||
begin
|
||||
{$ifdef CD_X11_SmartPaint}
|
||||
AWindowInfo.Valid:= False; // Needs full Painting
|
||||
{$endif}
|
||||
//SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN, SIZEZOOMSHOW, SIZEZOOMHIDE.
|
||||
LCLSendSizeMsg(AWinControl, Event.Width, Event.Height, SIZENORMAL);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user