mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-15 14:59:22 +02:00
Gtk2: fixed setCapture(), now it uses new way of capturing, old can be used with -dGTK2_USE_OLD_CAPTURE.
fixed unwanted focus grab of THintWindow. fixed bug when scrollbar button double clicked, we need 2 clicks to focus our client area. Fixed bugs #13878 #17596. git-svn-id: trunk@27638 -
This commit is contained in:
parent
923c7f1753
commit
afb190401d
@ -1277,11 +1277,12 @@ function gtkMotionNotify(Widget:PGTKWidget; Event: PGDKEventMotion;
|
||||
var
|
||||
DesignOnlySignal: boolean;
|
||||
ShiftState: TShiftState;
|
||||
{$IFNDEF GTK2_USE_OLD_CAPTURE}
|
||||
W: PGtkWidget;
|
||||
{$ENDIF}
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
|
||||
MousePositionValid:=false;
|
||||
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
DesignOnlySignal:=GetDesignOnlySignalFlag(Widget,dstMouseMotion);
|
||||
DebugLn('[GTKMotionNotify] ',
|
||||
@ -1295,12 +1296,22 @@ begin
|
||||
UpdateMouseCaptureControl;
|
||||
|
||||
ShiftState := GTKEventStateToShiftState(Event^.State);
|
||||
if (MouseCaptureWidget=Widget)
|
||||
and (MouseCaptureType=mctGTK)
|
||||
and ([ssLeft,ssRight,ssMiddle]*ShiftState=[]) then begin
|
||||
|
||||
if (MouseCaptureWidget = Widget) and (MouseCaptureType = mctGTK) and
|
||||
([ssLeft,ssRight,ssMiddle]*ShiftState=[]) then
|
||||
begin
|
||||
{$IFNDEF GTK2_USE_OLD_CAPTURE}
|
||||
W := gtk_grab_get_current;
|
||||
{$ENDIF}
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
DebugLn(['gtkMotionNotify gtk capture without mouse down: ',GetWidgetDebugReport(Widget)]);
|
||||
{$ENDIF}
|
||||
{$IFNDEF GTK2_USE_OLD_CAPTURE}
|
||||
if W = nil then
|
||||
SetCapture(0)
|
||||
else
|
||||
gtk_grab_remove(W);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
if not (csDesigning in TComponent(Data).ComponentState) then
|
||||
@ -1331,7 +1342,6 @@ function GTKMotionNotifyAfter(widget:PGTKWidget; event: PGDKEventMotion;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
begin
|
||||
Result := true; // stop event propagation
|
||||
MousePositionValid := False;
|
||||
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
DebugLn('[GTKMotionNotifyAfter] ',
|
||||
@ -1364,6 +1374,33 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
We must stop delivery of events from scrollbars of GtkScrollable, otherwise
|
||||
if we make an double click on scollbar button, and after that click into
|
||||
our control client area we need 2 click to make it focused.
|
||||
gtk_signal_connect_after() is used, otherwise our scrollbar won't react on
|
||||
such event.
|
||||
-------------------------------------------------------------------------------}
|
||||
function gtk2ScrollBarMouseBtnPress(widget: PGtkWidget; event: pgdkEventButton;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
We must stop delivery of events from scrollbars of GtkScrollable, otherwise
|
||||
if we make an double click on scollbar button, and after that click into
|
||||
our control client area we need 2 click to make it focused.
|
||||
gtk_signal_connect_after() is used, otherwise our scrollbar won't react on
|
||||
such event.
|
||||
-------------------------------------------------------------------------------}
|
||||
function gtk2ScrollBarMouseBtnRelease(widget: PGtkWidget; event: pgdkEventButton;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
gtkMouseBtnPress
|
||||
Params: widget: PGTKWidget; event: PGDKEventMotion; data: gPointer
|
||||
@ -1429,7 +1466,6 @@ var
|
||||
{$ENDIF}
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
MousePositionValid := False;
|
||||
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
AWinControl := TWinControl(Data);
|
||||
@ -1640,7 +1676,6 @@ var
|
||||
end;
|
||||
|
||||
begin
|
||||
MousePositionValid := False;
|
||||
|
||||
EventXY := Point(TruncToInt(Event^.X), TruncToInt(Event^.Y));
|
||||
ShiftState := GTKEventStateToShiftState(Event^.State);
|
||||
@ -1709,7 +1744,6 @@ function gtkMouseBtnPressAfter(widget: PGtkWidget; event : pgdkEventButton;
|
||||
data: gPointer) : GBoolean; cdecl;
|
||||
begin
|
||||
Result := True;
|
||||
MousePositionValid := False;
|
||||
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
debugln('[gtkMouseBtnPressAfter] ',
|
||||
@ -1822,7 +1856,6 @@ var
|
||||
DesignOnlySignal: boolean;
|
||||
begin
|
||||
Result := CallBackDefaultReturn;
|
||||
MousePositionValid := False;
|
||||
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
DesignOnlySignal:=GetDesignOnlySignalFlag(Widget,dstMouseRelease);
|
||||
@ -1856,7 +1889,6 @@ begin
|
||||
Result := not CallBackDefaultReturn;
|
||||
end;
|
||||
end;
|
||||
|
||||
if DeliverMouseUpMessage(Widget, Event, TWinControl(Data)) then
|
||||
Result := not CallBackDefaultReturn;
|
||||
end;
|
||||
@ -1873,7 +1905,6 @@ function gtkMouseBtnReleaseAfter(widget: PGtkWidget; event : pgdkEventButton;
|
||||
data: gPointer) : GBoolean; cdecl;
|
||||
begin
|
||||
Result := True;
|
||||
MousePositionValid := False;
|
||||
|
||||
{$IFDEF VerboseMouseBugfix}
|
||||
DebugLn('[gtkMouseBtnReleaseAfter] ',DbgSName(TObject(Data)),' ',
|
||||
|
@ -61,7 +61,6 @@ var
|
||||
MouseCaptureWidget: PGtkWidget;
|
||||
MouseCaptureType: TMouseCaptureType;
|
||||
MouseCaptureIndex: cardinal;
|
||||
MousePositionValid: boolean = false;
|
||||
MousePosition: TPoint;
|
||||
MousePositionTime: TDateTime;
|
||||
|
||||
|
@ -4467,6 +4467,9 @@ var
|
||||
OldMouseCaptureWidget,
|
||||
CurMouseCaptureWidget: PGtkWidget;
|
||||
begin
|
||||
{$IFNDEF GTK2_USE_OLD_CAPTURE}
|
||||
exit;
|
||||
{$ENDIF}
|
||||
OldMouseCaptureWidget:=MouseCaptureWidget;
|
||||
CurMouseCaptureWidget:=gtk_grab_get_current;
|
||||
|
||||
@ -4510,7 +4513,7 @@ begin
|
||||
{$ENDIF}
|
||||
if not (Owner in [mctGTKIntf,mctLCL]) then exit;
|
||||
// not every widget can capture the mouse
|
||||
CaptureWidget:=GetDefaultMouseCaptureWidget(Widget);
|
||||
CaptureWidget := GetDefaultMouseCaptureWidget(Widget);
|
||||
if CaptureWidget=nil then exit;
|
||||
|
||||
UpdateMouseCaptureControl;
|
||||
@ -4548,7 +4551,7 @@ var
|
||||
LCLObject: TObject;
|
||||
CanCapture: Boolean;
|
||||
Parent: TWinControl;
|
||||
{$IFDEF DEBUG_GTK_MOUSECAPTURE}
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
CurrentGrab: PGtkWidget;
|
||||
GrabInfo: PWinWidgetInfo;
|
||||
{$ENDIF}
|
||||
@ -4571,7 +4574,6 @@ begin
|
||||
|
||||
if CanCapture then
|
||||
begin
|
||||
|
||||
if GTK_IS_NOTEBOOK(PGtkWidget(TWinControl(LCLObject).Handle)) then
|
||||
exit;
|
||||
|
||||
@ -4584,7 +4586,7 @@ begin
|
||||
WidgetInfo:=GetWidgetInfo(PGtkWidget(TWinControl(LCLObject).Handle),false);
|
||||
if WidgetInfo <> nil then
|
||||
begin
|
||||
{$IFDEF DEBUG_GTK_MOUSECAPTURE}
|
||||
{$IFDEF VerboseMouseCapture}
|
||||
CurrentGrab := gtk_grab_get_current;
|
||||
writeln('GetDefaultMouseCaptureWidget: ',TWinControl(LCLObject).ClassName,' core ',
|
||||
dbghex(PtrUInt(WidgetInfo^.CoreWidget)),' client ',dbghex(PtrUInt(WidgetInfo^.ClientWidget)),
|
||||
|
@ -151,6 +151,14 @@ function ControlGetsMouseDownBefore(AControl: TControl;
|
||||
AWidget: PGtkWidget): boolean;
|
||||
procedure DeliverMouseDownMessage(widget: PGtkWidget; event: pgdkEventButton;
|
||||
AWinControl: TWinControl);
|
||||
|
||||
function gtk2ScrollBarMouseBtnPress(widget: PGtkWidget; event: pgdkEventButton;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
|
||||
function gtk2ScrollBarMouseBtnRelease(widget: PGtkWidget; event: pgdkEventButton;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
|
||||
|
||||
function gtkMouseBtnPress(widget: PGtkWidget; event: pgdkEventButton;
|
||||
data: gPointer): GBoolean; cdecl;
|
||||
function gtkMouseBtnPressAfter(widget: PGtkWidget; event: pgdkEventButton;
|
||||
|
@ -912,8 +912,23 @@ end;
|
||||
|
||||
procedure TGtk2WidgetSet.SetCommonCallbacks(const AGTKObject: PGTKObject;
|
||||
const ALCLObject: TObject);
|
||||
var
|
||||
Widget: PGtkWidget;
|
||||
begin
|
||||
// original gtk1 code
|
||||
if GTK_IS_SCROLLED_WINDOW(AGtkObject) then
|
||||
begin
|
||||
Widget := PGtkWidget(AGTKObject);
|
||||
g_signal_connect_after(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-press-event',
|
||||
TGCallback(@gtk2ScrollBarMouseBtnPress), ALCLObject);
|
||||
g_signal_connect_after(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-release-event',
|
||||
TGCallback(@gtk2ScrollBarMouseBtnRelease), ALCLObject);
|
||||
|
||||
g_signal_connect_after(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-press-event',
|
||||
TGCallback(@gtk2ScrollBarMouseBtnPress), ALCLObject);
|
||||
g_signal_connect_after(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-release-event',
|
||||
TGCallback(@gtk2ScrollBarMouseBtnRelease), ALCLObject);
|
||||
end;
|
||||
|
||||
SetCallback(LM_SHOWWINDOW, AGTKObject, ALCLObject);
|
||||
SetCallback(LM_DESTROY, AGTKObject, ALCLObject);
|
||||
SetCallback(LM_FOCUS, AGTKObject, ALCLObject);
|
||||
|
@ -7738,6 +7738,9 @@ end;
|
||||
function TGtk2WidgetSet.SetCapture(AHandle: HWND): HWND;
|
||||
var
|
||||
Widget: PGtkWidget;
|
||||
{$IFNDEF GTK2_USE_OLD_CAPTURE}
|
||||
CaptureWidget: PGtkWidget;
|
||||
{$ENDIF}
|
||||
begin
|
||||
Assert(False, Format('Trace:> [TGtk2WidgetSet.SetCapture] 0x%x', [AHandle]));
|
||||
Widget := PGtkWidget(AHandle);
|
||||
@ -7748,8 +7751,31 @@ begin
|
||||
// return old capture handle
|
||||
Result := GetCapture;
|
||||
|
||||
{$IFDEF GTK2_USE_OLD_CAPTURE}
|
||||
// capture
|
||||
CaptureMouseForWidget(Widget, mctLCL);
|
||||
{$ELSE}
|
||||
|
||||
if Result <> 0 then
|
||||
gtk_grab_remove(gtk_grab_get_current);
|
||||
|
||||
MouseCaptureWidget := nil;
|
||||
|
||||
if Widget = nil then
|
||||
exit;
|
||||
|
||||
CaptureWidget := GetDefaultMouseCaptureWidget(Widget);
|
||||
if CaptureWidget = nil then exit;
|
||||
|
||||
if not gtk_widget_has_focus(CaptureWidget) then
|
||||
gtk_widget_grab_focus(CaptureWidget);
|
||||
|
||||
gtk_grab_add(CaptureWidget);
|
||||
MouseCaptureWidget := CaptureWidget;
|
||||
if MouseCaptureWidget<>nil then
|
||||
SendMessage(HWnd(PtrUInt(MouseCaptureWidget)), LM_CAPTURECHANGED, 0,
|
||||
Result);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
|
@ -228,11 +228,13 @@ begin
|
||||
gtk_widget_size_allocate(Widget, @Allocation);
|
||||
|
||||
Set_RC_Name(AWinControl, Widget);
|
||||
|
||||
|
||||
TGtk2WSWinControl.SetCallbacks(GTK_OBJECT(Widget), AWinControl);
|
||||
|
||||
g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'change-value', TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
|
||||
g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value', TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
|
||||
g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'change-value',
|
||||
TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
|
||||
g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value',
|
||||
TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
|
||||
|
||||
g_signal_connect(Widget, 'scroll-event', TGCallback(@Gtk2ScrolledWindowScrollCB), WidgetInfo);
|
||||
end;
|
||||
|
@ -813,13 +813,15 @@ var
|
||||
begin
|
||||
ACustomForm := TCustomForm(AWinControl);
|
||||
|
||||
p := gtk_window_new(gtk_window_popup);
|
||||
p := gtk_window_new(GTK_WINDOW_POPUP);
|
||||
WidgetInfo := CreateWidgetInfo(p, AWinControl, AParams);
|
||||
gtk_window_set_policy(GTK_WINDOW(p), 0, 0, 0);
|
||||
gtk_window_set_focus_on_map(P, False);
|
||||
|
||||
// Create the form client area
|
||||
TempWidget := CreateFixedClientWidget;
|
||||
gtk_container_add(p, TempWidget);
|
||||
GTK_WIDGET_UNSET_FLAGS(TempWidget, GTK_CAN_FOCUS);
|
||||
gtk_widget_show(TempWidget);
|
||||
SetFixedWidget(p, TempWidget);
|
||||
SetMainWidget(p, TempWidget);
|
||||
|
Loading…
Reference in New Issue
Block a user