398
function Gtk2TranslateScrollStyle(const SS: TScrollStyle): TPoint;
401
ssAutoBoth: Result:=Point(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
402
ssAutoHorizontal: Result:=Point(GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
403
ssAutoVertical: Result:=Point(GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
404
ssBoth: Result:=Point(GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);
405
ssHorizontal: Result:=Point(GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
406
ssNone: Result:=Point(GTK_POLICY_NEVER, GTK_POLICY_NEVER);
407
ssVertical: Result:=Point(GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
398
411
{------------------------------------------------------------------------------
399
412
function GtkWidgetIsA(Widget: PGtkWidget; AType: TGtkType): boolean;
698
711
procedure InvalidateLastWFPResult(AControl: TWinControl; const ABounds: TRect);
700
713
if PtInRect(ABounds, LastWFPMousePos) and
701
GTK_IS_OBJECT(Pointer(LastWFPResult)) then
714
GTK_IS_OBJECT({%H-}Pointer(LastWFPResult)) then
703
716
if (AControl <> nil) and (AControl.Handle = LastWFPResult) and
704
717
AControl.Enabled and AControl.Visible then
706
g_signal_handlers_disconnect_by_func(GPointer(LastWFPResult),
719
g_signal_handlers_disconnect_by_func({%H-}GPointer(LastWFPResult),
707
720
TGTKSignalFunc(@DestroyWindowFromPointCB), nil);
708
721
LastWFPResult := 0;
709
722
LastWFPMousePos := Point(High(Integer), High(Integer));
806
819
if Gtk2WidgetSet.GetDesktopWidget <> nil then
807
820
gtk_window_set_transient_for(GtkWindow, PGtkWindow(Gtk2WidgetSet.GetDesktopWidget));
808
// gtk_widget_set_parent(GtkWindow, Gtk2WidgetSet.GetDesktopWidget);
810
822
{$IFNDEF gtk_no_set_modal}
811
823
gtk_window_set_modal(GtkWindow, true);
826
gtk_window_present(GtkWindow);
814
828
if (AForm <> nil) and (AForm.ShowInTaskBar <> stAlways) and
815
829
(gtk_window_get_type_hint(GtkWindow) <> GDK_WINDOW_TYPE_HINT_DIALOG) then
816
830
gtk_window_set_skip_taskbar_hint(GtkWindow, True);
817
gtk_window_present(GtkWindow);
818
832
{$IFDEF VerboseTransient}
819
833
DebugLn('TGtkWidgetSet.ShowModal ',Sender.ClassName);
821
//TGtk2WidgetSet(WidgetSet).
822
835
GTK2WidgetSet.UpdateTransientWindows;
1214
1227
DestLeft := DestWidget^.allocation.x - Offset.x + ((WindowWidth-ImageWidth) div 2);
1215
1228
if CenterVertically then
1216
1229
DestTop := DestWidget^.allocation.y - Offset.y + ((WindowHeight-ImageHeight) div 2);
1217
DestDC := GetDC(HDC(PtrUInt(DestWidget)));
1230
DestDC := GetDC(HDC({%H-}PtrUInt(DestWidget)));
1219
1232
//DebugLn('DrawImageListIconOnWidget B DestXY=',DestLeft,',',DestTop,
1220
1233
// ' DestWindowSize=',WindowWidth,',',WindowWidth,
2064
2078
Item: TMenuItem;
2065
MenuItemWidget: PGtkWidget;
2068
2081
if (AMenuItem=nil) or (not AMenuItem.HandleAllocated) then exit;
2069
2082
for i:=0 to AMenuItem.Count-1 do begin
2070
2083
Item:=AMenuItem[i];
2071
2084
if not Item.HandleAllocated then continue;
2072
if not GTK_WIDGET_SENSITIVE(PGTKWidget(Item.Handle)) then continue;
2073
if IsAccel(Msg.CharCode,Item.Caption) then begin
2076
MenuItemWidget:=PGTKWidget(Item.Handle);
2077
if GtkWidgetIsA(MenuItemWidget,gtk_menu_item_get_type) then begin
2078
//DebugLn(['CheckMenuChilds popup: ',dbgsName(Item)]);
2079
// popup the submenu
2080
gtk_signal_emit_by_name(PGtkObject(MenuItemWidget),'activate-item');
2085
if not GTK_WIDGET_SENSITIVE({%H-}PGTKWidget(Item.Handle)) then continue;
2086
if IsAccel(Msg.CharCode,Item.Caption) then Result:=true;
2147
2150
// the gtk2 gtkentry handles the return key and emits an activate signal
2148
2151
// The LCL does not use that and needs the return key event
2149
2152
// => emulate it
2150
if GtkWidgetIsA(TargetWidget, gtk_type_entry)
2151
and (gdk_event_get_type(AEvent) = GDK_KEY_PRESS)
2154
//DebugLn(['EmulateKeysEatenByGtk ']);
2154
// emulate VK_RETURN on GtkButton. issue #21483
2155
// spin button needs VK_RETURN to send OnEditingDone. issue #21224
2156
if GtkWidgetIsA(TargetWidget, gtk_type_button) or
2157
GtkWidgetIsA(TargetWidget, gtk_type_spin_button) then
2159
if (gdk_event_get_type(AEvent) = GDK_KEY_RELEASE) and
2160
(VKey = VK_RETURN) then
2162
FillChar(Msg, SizeOf(Msg), 0);
2163
Msg.CharCode := VKey;
2165
Msg.msg := LM_SYSKEYUP
2167
Msg.msg := LM_KEYUP;
2168
Msg.KeyData := CommonKeyData or (Flags shl 16) or $0001 {TODO: repeatcount};
2169
// do not send next LM_CLICKED. issue #21483
2170
g_object_set_data(PGObject(TargetWidget),'lcl-button-stop-clicked', TargetWidget);
2171
NotifyApplicationUserInput(TControl(TargetObj), Msg.Msg);
2172
DeliverKeyMessage(TargetObj, Msg);
2178
GtkWidgetIsA(TargetWidget, gtk_type_entry) or
2179
GtkWidgetIsA(TargetWidget, gtk_type_text_view)
2182
(gdk_event_get_type(AEvent) = GDK_KEY_PRESS) and
2183
((VKey = VK_RETURN) or (VKey = VK_TAB)) then
2185
// DebugLn(['EmulateKeysEatenByGtk ']);
2155
2186
FillChar(Msg, SizeOf(Msg), 0);
2156
2187
Msg.CharCode := VKey;
2242
2273
//DebugLn(['HandleGTKKeyUpDown TargetWidget=',GetWidgetDebugReport(TargetWidget),' ',DbgStr(EventString),' state=',AEvent^.state,' keyval=',AEvent^.keyval]);
2243
2274
FillChar(Msg, SizeOf(Msg), 0);
2245
gdk_event_key_get_string(AEvent, EventString);
2276
gdk_event_key_get_string(AEvent, EventString{%H-});
2246
2277
//DebugLn(['HandleGTKKeyUpDown TargetWidget=',GetWidgetDebugReport(TargetWidget),' ',DbgStr(EventString),' state=',AEvent^.state,' keyval=',AEvent^.keyval]);
2364
2396
{$IFDEF VerboseKeyboard}
2365
debugln('[HandleGTKKeyUpDown] GDK_KEY_PRESS UTF8="',DbgStr(Character),'"');
2397
debugln('[HandleGTKKeyUpDown] GDK_KEY_PRESS UTF8="',DbgStr(Character),'"',
2398
' EventStopped ',dbgs(EventStopped),' CanSendChar ',dbgs(CanSendChar));
2401
// we must pass KeyPress if UTF8KeyPress returned false result. issue #21489
2402
if Character <> '' then
2370
2404
LCLObject := GetNearestLCLObject(TargetWidget);
2371
if LCLObject is TWinControl
2405
if LCLObject is TWinControl then
2373
2407
OldCharacter := Character;
2374
2408
// send the key after navigation keys were handled
2375
2409
Result := TWinControl(LCLObject).IntfUTF8KeyPress(Character, 1, SysKey);
2376
if Result or (Character = '')
2378
else if (Character <> OldCharacter)
2410
if Result or (Character = '') then
2413
if (Character <> OldCharacter) then
2380
2415
WS := UTF8ToUTF16(Character);
2381
2416
if Length(WS) > 0 then
2397
2432
AEvent^.length := 1;
2437
PassUTF8AsKeyPress := not EventStopped and not Result;
2406
2441
// send a normal KeyPress Event for Delphi compatibility
2407
if not EventStopped and CanSendChar
2442
if not EventStopped and (CanSendChar or PassUTF8AsKeyPress) then
2409
2444
{$IFDEF EventTrace}
2410
2445
EventTrace('char', data);
2413
2448
KeyPressesChar := #0;
2414
if AEvent^.Length = 1
2449
if AEvent^.Length = 1 then
2416
2451
// ASCII key was pressed
2417
2452
KeyPressesChar := EventString^;
2420
2455
KeyPressesChar := GetSpecialChar;
2456
//NonAscii key was pressed, and UTF8KeyPress didn't handle it.issue #21489
2457
if PassUTF8AsKeyPress and (KeyPressesChar = #0) then
2458
KeyPressesChar := Char($3F);
2422
if KeyPressesChar <> #0
2461
if KeyPressesChar <> #0 then
2424
2463
FillChar(Msg, SizeOf(Msg), 0);
2426
2465
Msg.KeyData := CommonKeyData;
2429
2468
// send the (Sys)Char message directly (not queued) to the LCL
2431
2470
Msg.CharCode := Ord(KeyPressesChar);
2432
if DeliverKeyMessage(TargetObj, Msg)
2433
and (Ord(KeyPressesChar) <> Msg.CharCode)
2471
if DeliverKeyMessage(TargetObj, Msg) and
2472
(Ord(KeyPressesChar) <> Msg.CharCode) then
2435
2474
// key was changed by lcl
2436
if (Msg.CharCode=0) or (Msg.CharCode>=128)
2475
if (Msg.CharCode=0) or (Msg.CharCode>=128) then
2438
2477
// key set to invalid => just stop
2442
2481
// try to change the key
2443
2482
CharToKeyVal(chr(Msg.CharCode), AEvent^.KeyVal, AEvent^.length);
2444
2483
if AEvent^.length = 1 then
2446
2485
EventString^ := Character[1];
2447
2486
EventString[1] := #0;
2450
2488
EventString^ := #0;
2451
2489
gdk_event_key_set_string(AEvent, EventString);
3060
3098
procedure UpdateModifierMap(const AModMap: TModMap; AKeyCode: Byte; AKeySym: Cardinal);
3061
3100
{$ifdef VerboseModifiermap}
3063
STATE_NAME: array[TShiftStateEnum] of String = ('ssShift', 'ssAlt', 'ssCtrl',
3064
'ssLeft', 'ssRight', 'ssMiddle', 'ssDouble',
3065
'ssMeta', 'ssSuper', 'ssHyper', 'ssAltGr', 'ssCaps', 'ssNum',
3066
'ssScroll', 'ssTriple', 'ssQuad', 'ssExtra1', 'ssExtra2');
3069
3103
ShiftState: TShiftStateEnum;
3071
3105
if AModMap[AKeyCode] = 0 then Exit;
3100
3134
MModifiers[ShiftState].UseValue := False;
3102
3136
{$ifdef VerboseModifiermap}
3103
DebugLn('Mapped keycode=%u, keysym=$%x, modifier=$%2.2x to shiftstate %s', [AKeyCode, AKeySym, AModMap[AKeyCode], STATE_NAME[ShiftState]]);
3137
WriteStr(s, ShiftState);
3138
DebugLn('Mapped keycode=%u, keysym=$%x, modifier=$%2.2x to shiftstate %s',
3139
[AKeyCode, AKeySym, AModMap[AKeyCode], s]);
3211
3247
for m := 0 to KeySymCount - 1 do
3213
3249
if KeySyms[m] = 0 then Continue;
3214
FindVKeyInfo(KeySyms[m], VKey, Extended, HasMultiVK, SecondKey);
3250
FindVKeyInfo(KeySyms[m], VKey, Extended{%H-}, HasMultiVK,{%H-} SecondKey);
3215
3251
{$ifdef Windows}
3216
3252
// on windows, the keycode is perdef the VK,
3217
3253
// we only enter this loop to set the correct flags
3709
3745
{-------------------------------------------------------------------------------
3710
Some need the HiddenLCLobject which created a parent of this widget.
3712
MWE: is this obsolete ?
3713
-------------------------------------------------------------------------------}
3714
procedure SetHiddenLCLObject(const Widget: Pointer; const AnObject: TObject);
3716
if (Widget <> nil) then
3717
gtk_object_set_data(Widget, 'LCLHiddenClass', Pointer(AnObject));
3720
function GetHiddenLCLObject(const Widget: Pointer): TObject;
3722
Result := TObject(gtk_object_get_data(Widget, 'LCLHiddenClass'));
3725
{-------------------------------------------------------------------------------
3726
3746
function GetNearestLCLObject(Widget: PGtkWidget): TObject;
3728
3748
Retrieves the LCLObject belonging to the widget. If the widget is created as
4031
4050
if (Info^.LCLObject is TWinControl) then begin
4032
4051
AWinControl:=TWinControl(Info^.LCLObject);
4033
4052
if AWinControl.HandleAllocated
4034
and (PGtkWidget(AWinControl.Handle)=Widget) then begin
4053
and ({%H-}PGtkWidget(AWinControl.Handle)=Widget) then begin
4035
4054
// send the LM_DESTROY message before destroying the widget
4036
FillChar(Mess,SizeOf(Mess),0);
4055
FillChar(Mess{%H-},SizeOf(Mess),0);
4037
4056
Mess.msg := LM_DESTROY;
4038
4057
DeliverMessage(Info^.LCLObject, Mess);
4290
4321
ThePage := TCustomPage(APage);
4291
TheNoteBook := TCustomNotebook(ANoteBook);
4322
TheNoteBook := TCustomTabControl(ANoteBook);
4292
4323
if (APage=nil) or (not ThePage.HandleAllocated) then exit;
4293
4324
if TheNoteBook=nil then begin
4294
TheNoteBook:=TCustomNotebook(ThePage.Parent);
4325
TheNoteBook:=TCustomTabControl(ThePage.Parent);
4295
4326
if TheNoteBook=nil then exit;
4297
NoteBookWidget:=PGtkWidget(TWinControl(TheNoteBook).Handle);
4298
PageWidget:=PGtkWidget(TWinControl(ThePage).Handle);
4328
NoteBookWidget:={%H-}PGtkWidget(TWinControl(TheNoteBook).Handle);
4329
PageWidget:={%H-}PGtkWidget(TWinControl(ThePage).Handle);
4300
4331
// get the tab container and the tab components: pixmap, label and closebtn
4301
4332
TabWidget:=gtk_notebook_get_tab_label(PGtkNoteBook(NotebookWidget),
4326
4357
UpdateTabCloseBtn;
4360
procedure UpdateNotebookTabFont(APage: TWinControl; AFont: TFont);
4362
NoteBookWidget: PGtkWidget;
4363
PageWidget: PGtkWidget;
4364
TabWidget: PGtkWidget;
4365
TabLabelWidget: PGtkWidget;
4368
NoteBookWidget:={%H-}PGtkWidget((APage.Parent).Handle);
4369
PageWidget:={%H-}PGtkWidget(APage.Handle);
4370
TabWidget:=gtk_notebook_get_tab_label(PGtkNoteBook(NotebookWidget),
4372
if TabWidget<>nil then
4373
TabLabelWidget:=gtk_object_get_data(PGtkObject(TabWidget), 'TabLabel')
4375
TabLabelWidget:=nil;
4377
// set new font to page
4378
Gtk2WidgetSet.SetWidgetFont(PageWidget, AFont);
4379
Gtk2WidgetSet.SetWidgetColor(PageWidget, AFont.Color, clNone,
4380
[GTK_STATE_NORMAL,GTK_STATE_ACTIVE,
4381
GTK_STATE_PRELIGHT,GTK_STATE_SELECTED,
4384
// set new font to tab
4386
if TabLabelWidget = nil then
4389
Gtk2WidgetSet.SetWidgetFont(TabLabelWidget, AFont);
4390
Gtk2WidgetSet.SetWidgetColor(TabLabelWidget, AFont.Color, clNone,
4391
[GTK_STATE_NORMAL,GTK_STATE_ACTIVE,
4392
GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]);
4330
4396
{-------------------------------------------------------------------------------
4331
4397
GetWidgetScreenPos
4452
4524
Result := GetWidgetOrigin(TheWidget);
4527
function GetWidgetClientRect(TheWidget: PGtkWidget): TRect;
4529
Widget, ClientWidget: PGtkWidget;
4532
procedure GetNoteBookClientRect(NBWidget: PGtkNotebook);
4535
PageWidget: PGtkWidget;
4536
FrameBorders: TRect;
4541
PageIndex:=gtk_notebook_get_current_page(NBWidget);
4542
if PageIndex>=0 then
4543
PageWidget:=gtk_notebook_get_nth_page(NBWidget,PageIndex)
4546
if (PageWidget<>nil) and GTK_WIDGET_RC_STYLE(PageWidget)
4547
and ((PageWidget^.Allocation.Width>1) or (PageWidget^.Allocation.Height>1))
4549
// get the size of the current page
4550
Result.Right:=PageWidget^.Allocation.Width;
4551
Result.Bottom:=PageWidget^.Allocation.Height;
4552
//DebugLn(['GetNoteBookClientRect using pagewidget: ',GetWidgetDebugReport(Widget),' ARect=',dbgs(aRect)]);
4555
FrameBorders:=GetStyleNotebookFrameBorders;
4556
aWidth:=Widget^.allocation.width;
4557
aHeight:=Widget^.allocation.height;
4559
Max(0,AWidth-FrameBorders.Left-FrameBorders.Right),
4560
Max(0,aHeight-FrameBorders.Top-FrameBorders.Bottom));
4561
//DebugLn(['GetNoteBookClientRect using defaults: ',GetWidgetDebugReport(Widget),' ARect=',dbgs(aRect),' Frame=',dbgs(FrameBorders)]);
4565
Result := Rect(0, 0, 0, 0);
4566
Widget := TheWidget;
4567
ClientWidget := GetFixedWidget(Widget);
4568
if (ClientWidget <> nil) then
4569
Widget := ClientWidget;
4570
if (Widget <> nil) then
4572
Result.Right:=Widget^.Allocation.Width;
4573
Result.Bottom:=Widget^.Allocation.Height;
4574
if GtkWidgetIsA(Widget,gtk_notebook_get_type) then
4575
GetNoteBookClientRect(PGtkNoteBook(Widget))
4577
if GTK_IS_SCROLLED_WINDOW(Widget) and GTK_IS_BIN(Widget) then
4579
AChild := gtk_bin_get_child(PGtkBin(Widget));
4580
if (AChild <> nil) and GTK_IS_TREE_VIEW(AChild) then
4582
Result.Right := AChild^.allocation.width - AChild^.allocation.x;
4583
Result.Bottom := AChild^.allocation.height - AChild^.allocation.y;
4587
{$IfDef VerboseGetClientRect}
4588
if ClientWidget<>nil then begin
4589
DebugLn('GetClientRect Widget=',GetWidgetDebugReport(PgtkWidget(Handle)),
4590
' Client=',DbgS(ClientWidget),WidgetFlagsToString(ClientWidget),
4591
' WindowSize=',dbgs(Result.Right),',',dbgs(Result.Bottom),
4592
' Allocation=',dbgs(ClientWidget^.Allocation.Width),',',dbgs(ClientWidget^.Allocation.Height)
4595
DebugLn('GetClientRect Widget=',GetWidgetDebugReport(PgtkWidget(Handle)),
4596
' Client=',DbgS(ClientWidget),WidgetFlagsToString(ClientWidget),
4597
' WindowSize=',dbgs(Result.Right),',',dbgs(Result.Bottom),
4598
' Allocation=',dbgs(Widget^.Allocation.Width),',',dbgs(Widget^.Allocation.Height)
4601
if GetLCLObject(Widget) is TCustomPage then begin
4602
DebugLn(['TGtk2WidgetSet.GetClientRect Rect=',dbgs(Result),' ',GetWidgetDebugReport(Widget)]);
4455
4607
{-------------------------------------------------------------------------------
4456
4608
TranslateGdkPointToClientArea
4497
{------------------------------------------------------------------------------
4498
Function: UpdateMouseCaptureControl
4502
Sets MouseCaptureWidget to the current capturing widget.
4503
------------------------------------------------------------------------------}
4504
procedure UpdateMouseCaptureControl;
4506
OldMouseCaptureWidget,
4507
CurMouseCaptureWidget: PGtkWidget;
4509
{$IFNDEF GTK2_USE_OLD_CAPTURE}
4512
OldMouseCaptureWidget:=MouseCaptureWidget;
4513
CurMouseCaptureWidget:=gtk_grab_get_current;
4515
if OldMouseCaptureWidget<>CurMouseCaptureWidget then begin
4516
// the mouse grab changed
4517
// -> this means the gtk itself has changed the mouse grab
4518
{$IFDEF VerboseMouseCapture}
4519
DebugLn('UpdateMouseCaptureControl Capture changed from ',
4520
'[',GetWidgetDebugReport(OldMouseCaptureWidget),' type=',MouseCaptureTypeNames[MouseCaptureType],']',
4521
' to [',GetWidgetDebugReport(CurMouseCaptureWidget),' type=GTK]');
4522
if CurMouseCaptureWidget<>nil then
4523
DebugLn('parent ', GetWidgetDebugReport(CurMouseCaptureWidget^.Parent));
4526
// notify the new capture control
4527
MouseCaptureWidget:=CurMouseCaptureWidget;
4528
MouseCaptureType:=mctGTK;
4529
if MouseCaptureWidget<>nil then begin
4530
// the MouseCaptureWidget is probably not a main widget
4531
SendMessage(HWnd(PtrUInt(MouseCaptureWidget)), LM_CAPTURECHANGED, 0,
4532
HWnd(PtrUInt(OldMouseCaptureWidget)));
4537
4649
procedure IncreaseMouseCaptureIndex;
4539
4651
if MouseCaptureIndex<$ffffffff then
4542
4654
MouseCaptureIndex:=0;
4545
{$IFDEF GTK2_USE_OLD_CAPTURE}
4546
procedure CaptureMouseForWidget(Widget: PGtkWidget; Owner: TMouseCaptureType);
4548
CaptureWidget: PGtkWidget;
4551
{$IFDEF VerboseMouseCapture}
4552
DebugLn('CaptureMouseForWidget START ',GetWidgetDebugReport(Widget));
4554
if not (Owner in [mctGTKIntf,mctLCL]) then exit;
4555
// not every widget can capture the mouse
4556
CaptureWidget := GetDefaultMouseCaptureWidget(Widget);
4557
if CaptureWidget=nil then exit;
4559
UpdateMouseCaptureControl;
4560
if (MouseCaptureType<>mctGTK) then begin
4562
if (MouseCaptureWidget=CaptureWidget) then begin
4563
// we are already capturing this widget
4566
// release old capture
4567
ReleaseMouseCapture;
4570
{$IFDEF VerboseMouseCapture}
4571
DebugLn('CaptureMouseForWidget Start Capturing for ',GetWidgetDebugReport(CaptureWidget));
4573
IncreaseMouseCaptureIndex;
4574
NowIndex:=MouseCaptureIndex;
4575
if not gtk_widget_has_focus(CaptureWidget) then
4576
gtk_widget_grab_focus(CaptureWidget);
4577
if NowIndex=MouseCaptureIndex then begin
4578
{$IFDEF VerboseMouseCapture}
4579
DebugLn('CaptureMouseForWidget Commit Capturing for ',GetWidgetDebugReport(CaptureWidget));
4581
MouseCaptureWidget:=CaptureWidget;
4582
MouseCaptureType:=Owner;
4583
gtk_grab_add(CaptureWidget);
4588
4657
function GetDefaultMouseCaptureWidget(Widget: PGtkWidget
4616
4685
if CanCapture then
4618
if GTK_IS_NOTEBOOK(PGtkWidget(TWinControl(LCLObject).Handle)) then
4687
if GTK_IS_NOTEBOOK({%H-}PGtkWidget(TWinControl(LCLObject).Handle)) then
4621
4690
Parent := TWinControl(LCLObject).Parent;
4622
4691
if Assigned(Parent) then
4624
if GTK_IS_NOTEBOOK(PGtkWidget(Parent.Handle)) then
4693
if GTK_IS_NOTEBOOK({%H-}PGtkWidget(Parent.Handle)) then
4627
WidgetInfo:=GetWidgetInfo(PGtkWidget(TWinControl(LCLObject).Handle),false);
4696
WidgetInfo:=GetWidgetInfo({%H-}PGtkWidget(TWinControl(LCLObject).Handle),false);
4628
4697
if WidgetInfo <> nil then
4630
4699
{$IFDEF VerboseMouseCapture}
4631
4700
CurrentGrab := gtk_grab_get_current;
4632
writeln('GetDefaultMouseCaptureWidget: ',TWinControl(LCLObject).ClassName,' core ',
4633
dbghex(PtrUInt(WidgetInfo^.CoreWidget)),' client ',dbghex(PtrUInt(WidgetInfo^.ClientWidget)),
4634
' currentgrab ', dbghex(PtrUInt(CurrentGrab)));
4701
debugln(['GetDefaultMouseCaptureWidget: ',TWinControl(LCLObject).ClassName,
4702
' core ',dbghex({%H-}PtrUInt(WidgetInfo^.CoreWidget)),
4703
' client ',dbghex({%H-}PtrUInt(WidgetInfo^.ClientWidget)),
4704
' currentgrab ', dbghex({%H-}PtrUInt(CurrentGrab))]);
4635
4705
if CurrentGrab <> nil then
4637
4707
GrabInfo := GetWidgetInfo(CurrentGrab);
4638
4708
if GrabInfo <> nil then
4639
writeln('GetDefaultMouseCaptureWidget: CURRENT GRAB ',GrabInfo^.LCLObject.ClassName);
4709
debugln('GetDefaultMouseCaptureWidget: CURRENT GRAB ',GrabInfo^.LCLObject.ClassName);
4642
4712
if WidgetInfo^.ClientWidget <> nil then
4662
4739
OldMouseCaptureWidget: PGtkWidget;
4663
4740
Info: PWidgetInfo;
4742
OldMouseCaptureWidget := gtk_grab_get_current;
4743
if (OldMouseCaptureWidget=nil) and (MouseCaptureWidget=nil) then exit;
4665
4744
{$IFDEF VerboseMouseCapture}
4666
DebugLn('ReleaseMouseCapture ',dbgs(ord(MouseCaptureType)),' MouseCaptureWidget=[',GetWidgetDebugReport(MouseCaptureWidget),']');
4745
DebugLn('ReleaseMouseCapture gtk_grab=[',GetWidgetDebugReport(OldMouseCaptureWidget),'] MouseCaptureWidget=[',GetWidgetDebugReport(MouseCaptureWidget),']');
4668
if MouseCaptureType=mctGTK then
4747
Info := GetWidgetInfo(OldMouseCaptureWidget, false);
4748
if (Info <> nil) and (Info^.CoreWidget <> nil) then
4670
Info := GetWidgetInfo(gtk_grab_get_current, false);
4671
if (Info <> nil) and (Info^.CoreWidget <> nil) then
4750
if GtkWidgetIsA(Info^.CoreWidget, gtk_list_get_type) then
4673
if GtkWidgetIsA(Info^.CoreWidget, gtk_list_get_type) then
4676
// listbox grabs pointer and other control for itself, when we click on listbox item
4677
// also it changes its state to drag_selection
4678
// this is not expected in LCL and as result cause bugs, such as 7892
4679
// so we need end drag selection manually
4680
OldMouseCaptureWidget := Info^.CoreWidget;
4681
gtk_list_end_drag_selection(PGtkList(OldMouseCaptureWidget));
4753
// listbox grabs pointer and other control for itself, when we click on listbox item
4754
// also it changes its state to drag_selection
4755
// this is not expected in LCL and as result cause bugs, such as 7892
4756
// so we need end drag selection manually
4757
OldMouseCaptureWidget := Info^.CoreWidget;
4758
gtk_list_end_drag_selection(PGtkList(OldMouseCaptureWidget));
4686
OldMouseCaptureWidget:=MouseCaptureWidget;
4687
MouseCaptureWidget:=nil;
4688
MouseCaptureType:=mctGTK;
4689
if OldMouseCaptureWidget<>nil then
4762
if MouseCaptureWidget<>nil then begin
4763
{$IfDef VerboseMouseCapture}
4764
DebugLn('TGtk2WidgetSet.ReleaseMouseCapture gtk_grab_remove=[',GetWidgetDebugReport(OldMouseCaptureWidget),']');
4766
OldMouseCaptureWidget:=MouseCaptureWidget;
4767
MouseCaptureWidget:=nil;
4690
4768
gtk_grab_remove(OldMouseCaptureWidget);
4691
4770
// tell the LCL
4692
4771
SetCaptureControl(nil);
4765
4844
function GetDesignSignalMask(Widget: PGtkWidget): TDesignSignalMask;
4767
Result:=TDesignSignalMask(PtrUInt(gtk_object_get_data(PGtkObject(Widget),
4846
Result:=TDesignSignalMask({%H-}PtrUInt(gtk_object_get_data(PGtkObject(Widget),
4768
4847
'LCLDesignMask')));
4771
4850
procedure SetDesignSignalMask(Widget: PGtkWidget; NewMask: TDesignSignalMask);
4773
gtk_object_set_data(PGtkObject(Widget),'LCLDesignMask',Pointer(PtrInt(NewMask)));
4852
gtk_object_set_data(PGtkObject(Widget),'LCLDesignMask',{%H-}Pointer(PtrInt(NewMask)));
4776
4855
function GetDesignOnlySignalFlag(Widget: PGtkWidget;
4964
5034
procedure ConnectSignals(TheWidget: PGtkWidget);
4966
LCLObject, HiddenLCLObject: TObject;
4967
5037
DesignSignalType: TDesignSignalType;
4968
5038
DesignFlags: TConnectSignalFlags;
4970
5040
//if AWinControl is TListView then DebugLn('ConnectSignals A ',DbgS(TheWidget));
4971
5041
if TheWidget=nil then exit;
4973
5042
// check if TheWidget belongs to another LCL object
4974
5043
LCLObject:=GetLCLObject(TheWidget);
4975
HiddenLCLObject:=GetHiddenLCLObject(TheWidget);
4976
5044
if (LCLObject<>nil) and (LCLObject<>AWinControl) then begin
4979
if (HiddenLCLObject<>nil) and (HiddenLCLObject<>AWinControl) then begin
4983
5048
//if AWinControl is TListView then DebugLn('ConnectSignals B ',DbgS(TheWidget));
4984
5049
// connect signals needed for design mode:
5729
5790
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem; MenuItemWidget: PGtkWidget);
5731
UpdateInnerMenuItem(LCLMenuItem, MenuItemWidget, LCLMenuItem.ShortCut);
5792
UpdateInnerMenuItem(LCLMenuItem, MenuItemWidget, LCLMenuItem.ShortCut, LCLMenuItem.ShortCutKey2);
5734
5795
{------------------------------------------------------------------------------
5735
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem;
5736
MenuItemWidget: PGtkWidget; NewShortCut: TShortCut);
5738
5796
Update the inner widgets of a menuitem widget.
5739
5797
------------------------------------------------------------------------------}
5740
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem;
5741
MenuItemWidget: PGtkWidget; NewShortCut: TShortCut);
5798
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem; MenuItemWidget: PGtkWidget;
5799
NewShortCut, ShortCutKey2: TShortCut);
5743
5801
WidgetDirection : array[boolean] of longint = (GTK_TEXT_DIR_LTR, GTK_TEXT_DIR_RTL);
5766
5824
LabelWidget: PGtkLabel;
5767
5825
NeedShortCut: Boolean;
5827
Shift, Shift2: TShiftState;
5772
//DebugLn(['UpdateShortCutLabel ',dbgsName(LCLMenuItem),' ',ShortCutToText(NewShortCut)]);
5773
5830
ShortCutToKey(NewShortCut, Key, Shift);
5775
// check if shortcut is needed
5776
NeedShortCut := Key <> 0;
5779
(LCLMenuItem.Parent <> nil) and
5780
LCLMenuItem.Parent.HandleAllocated and
5781
GtkWidgetIsA(PGtkWidget(LCLMenuItem.Parent.Handle), GTK_TYPE_MENU_BAR) then
5783
// no shortcut captions for items in menubar
5784
NeedShortCut := False;
5787
LabelWidget := PGtkLabel(gtk_object_get_data(PGtkObject(MenuItemWidget),
5788
'LCLShortCutLabel'));
5831
ShortCutToKey(ShortCutKey2, Key2, Shift2);
5833
// Check if shortcut is needed. No shortcut captions for items in menubar
5834
NeedShortCut := (Key <> 0) and
5835
not ( (LCLMenuItem.Parent <> nil) and LCLMenuItem.Parent.HandleAllocated and
5836
GtkWidgetIsA({%H-}PGtkWidget(LCLMenuItem.Parent.Handle), GTK_TYPE_MENU_BAR) );
5838
LabelWidget := PGtkLabel(gtk_object_get_data(PGtkObject(MenuItemWidget),'LCLShortCutLabel'));
5790
5839
if NeedShortCut then
5792
ShortCutToKey(NewShortCut, Key, Shift);
5793
5841
s := GetAcceleratorString(Key, Shift);
5843
s := s + ', ' + GetAcceleratorString(Key2, Shift2);
5794
5844
// ShortCutToText(NewShortCut);
5795
5845
if LabelWidget = nil then
5987
6037
if TStatusBar(Data).Panels[ItemId].Style <> psOwnerDraw then
5990
FillChar(Msg, SizeOf(Msg), #0);
5991
FillChar(PS, SizeOf(PS), #0);
5992
FillChar(ItemStruct, SizeOf(ItemStruct), #0);
6040
FillChar(Msg{%H-}, SizeOf(Msg), #0);
6041
FillChar(PS{%H-}, SizeOf(PS), #0);
6042
FillChar(ItemStruct{%H-}, SizeOf(ItemStruct), #0);
5993
6043
New(ItemStruct);
5994
6044
// we must fill up complete area otherwise gtk2 will do
5995
6045
// strange paints when item is not fully exposed.
6299
6349
gtk_widget_size_request(Widget,@Requisition);
6300
6350
PreferredWidth:=Requisition.width;
6301
6351
PreferredHeight:=Requisition.height;
6302
if WithThemeSpace then begin
6305
//debugLn('GetGTKDefaultWidgetSize ',DbgSName(AWinControl),' ',dbgs(gtk_widget_get_xthickness(Widget)),' ythickness=',dbgs(gtk_widget_get_ythickness(Widget)));
6306
//debugLn(['GetGTKDefaultWidgetSize ',GetWidgetDebugReport(Widget)]);
6307
//dec(PreferredWidth,gtk_widget_get_xthickness(Widget));
6308
//if gtk_class_get_type(gtk_object_get_class(Widget))=GTK_TYPE_BUTTON then
6309
// dec(PreferredHeight,2*gtk_widget_get_ythickness(Widget));
6311
6352
{DebugLn(['GetGTKDefaultWidgetSize Allocation=',Widget^.allocation.x,',',Widget^.allocation.y,',',Widget^.allocation.width,',',Widget^.allocation.height,
6312
6353
' requisition=',Widget^.requisition.width,',',Widget^.requisition.height,
6313
6354
' PreferredWidth=',PreferredWidth,' PreferredHeight=',PreferredHeight,
6314
6355
' WithThemeSpace=',WithThemeSpace]);}
6316
6358
gtk_widget_set_size_request(Widget, AWinControl.Width, AWinControl.Height);
6317
6359
//debugln('GetGTKDefaultSize PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight));
6442
6484
Msg := LM_SIZE;
6443
6485
if LCLControl is TCustomForm then begin
6444
// if the LCL gets an event without a State it resets it to SIZENORMAL
6486
// if the LCL gets an event without a State it resets it to SIZE_RESTORED
6445
6487
// so we send it the state it already is
6446
6488
case TCustomForm(LCLControl).WindowState of
6447
wsNormal: SizeType := SIZENORMAL;
6448
wsMinimized: SizeType := SIZEICONIC;
6449
wsMaximized: SizeType := SIZEFULLSCREEN;
6489
wsNormal: SizeType := SIZE_RESTORED;
6490
wsMinimized: SizeType := SIZE_MINIMIZED;
6491
wsMaximized: SizeType := SIZE_MAXIMIZED;
6492
wsFullScreen: SizeType := SIZE_FULLSCREEN;
6646
6689
((LCLControl.Parent = nil) and (LCLControl.ParentWindow <> 0)) then
6648
6691
if LCLControl.Parent <> nil then
6649
ParentWidget := PGtkWidget(LCLControl.Parent.Handle)
6692
ParentWidget := {%H-}PGtkWidget(LCLControl.Parent.Handle)
6651
ParentWidget := PGtkWidget(LCLControl.ParentWindow);
6694
ParentWidget := {%H-}PGtkWidget(LCLControl.ParentWindow);
6652
6695
ParentFixed := GetFixedWidget(ParentWidget);
6653
6696
if GtkWidgetIsA(ParentFixed,GTK_FIXED_GET_TYPE) or
6654
6697
GtkWidgetIsA(ParentFixed,GTK_LAYOUT_GET_TYPE) then
7397
7440
TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
7398
7441
g_signal_connect(PGTKScrolledWindow(ScrolledWidget)^.vscrollbar, 'change-value',
7399
7442
TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
7443
g_signal_connect(PGTKScrolledWindow(ScrolledWidget)^.hscrollbar, 'button-press-event',
7444
TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
7445
g_signal_connect(PGTKScrolledWindow(ScrolledWidget)^.hscrollbar, 'button-release-event',
7446
TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
7447
g_signal_connect(PGTKScrolledWindow(ScrolledWidget)^.vscrollbar, 'button-press-event',
7448
TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
7449
g_signal_connect(PGTKScrolledWindow(ScrolledWidget)^.vscrollbar, 'button-release-event',
7450
TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
7445
7496
if StyleObject <> nil then
7447
if StyleObject^.Obj <> nil then
7448
gtk_object_destroy(StyleObject^.Obj);
7449
if StyleObject^.Widget <> nil then
7498
if StyleObject^.Owner <> nil then
7452
gtk_widget_unref(StyleObject^.Widget);
7454
gtk_widget_destroy(StyleObject^.Widget);
7500
// GTK owns the reference to top level widgets created by application,
7501
// so they cannot be destroyed by unreferencing.
7502
if GTK_WIDGET_TOPLEVEL(StyleObject^.Owner) then
7503
gtk_widget_destroy(StyleObject^.Owner)
7505
g_object_unref(StyleObject^.Owner);
7456
7507
if StyleObject^.Style <> nil then
7457
7508
if StyleObject^.Style^.attach_count > 0 then
7639
7690
If CompareText(WName,LazGtkStyleNames[lgsDefault])=0 then begin
7640
7691
lgs:=lgsDefault;
7641
7692
AddToStyleWindow:=false;
7643
StyleObject^.Widget :=
7644
// GTK2 does not allow to instantiate the abstract base Widget
7645
// so we use the "invisible" widget, which should never be defined
7647
GTK_WIDGET_NEW( GTK_TYPE_INVISIBLE, NoName,[]);
7693
AddReference:=false;
7694
// GTK2 does not allow to instantiate the abstract base Widget
7695
// so we use the "invisible" widget, which should never be defined
7697
// It is created with a real reference count=1 (not floating)
7698
// because it is a treated as top level widget.
7699
StyleObject^.Widget := gtk_invisible_new;
7650
7702
If CompareText(WName,LazGtkStyleNames[lgsWindow])=0 then begin
7651
7703
lgs:=lgsWindow;
7652
7704
StyleObject^.Widget := GTK_WINDOW_NEW(GTK_WINDOW_TOPLEVEL);
7653
7705
AddToStyleWindow:=false;
7706
AddReference:=false;
7654
7707
gtk_widget_hide(StyleObject^.Widget);
7655
7708
// create the fixed widget
7656
7709
// (where to put all style widgets, that need a parent for realize)
7675
7728
StyleObject^.Widget := GTK_RADIO_BUTTON_NEW(nil);
7678
If CompareText(WName,LazGtkStyleNames[lgsMenu])=0 then begin
7731
if CompareText(WName,LazGtkStyleNames[lgsMenu])=0 then
7680
7734
StyleObject^.Widget := gtk_menu_new;
7735
// we need REAL menu size for SM_CYMENU
7736
// menuitem will be destroyed with menu by gtk.
7737
VBox := gtk_menu_item_new_with_label('DUMMYITEM');
7738
gtk_menu_shell_append(PGtkMenuShell(StyleObject^.Widget), VBox);
7683
7741
If CompareText(WName,LazGtkStyleNames[lgsMenuBar])=0 then begin
7786
7842
If CompareText(WName,LazGtkStyleNames[lgsToolButton])=0 then begin
7787
7843
lgs:=lgsToolButton;
7788
StyleObject^.Widget := gtk_toolbar_append_item(PGtkToolBar(GetStyleWidget(lgsToolBar)), 'B', nil, nil, nil, nil, nil);
7844
StyleObject^.Widget := PGtkWidget(gtk_tool_button_new(nil, 'B'));
7845
gtk_toolbar_insert(PGtkToolbar(GetStyleWidget(lgsToolBar)), PGtkToolItem(StyleObject^.Widget), -1);
7791
7848
if CompareText(WName,LazGtkStyleNames[lgsScrolledWindow])=0 then begin
7810
7867
// consistency error
7811
7868
RaiseGDBException('');
7814
7871
// ensure style of the widget
7815
7872
If (StyleObject^.Widget <> nil) then begin
7816
gtk_widget_ref(StyleObject^.Widget);
7818
// put style widget on style window, so that it can be realized
7874
if not Assigned(StyleObject^.Owner) then
7875
StyleObject^.Owner := StyleObject^.Widget;
7877
// Widgets are created with a floating reference, except for top level.
7878
// Here the floating reference is acquired, or reference count increased
7879
// in case the floating reference is already owned (the widget has been
7880
// added to a container).
7881
if AddReference then
7883
if g_object_ref_sink = nil then
7885
// Deprecated since 2.10.
7886
gtk_object_ref(PGtkObject(StyleObject^.Owner));
7887
gtk_object_sink(PGtkObject(StyleObject^.Owner));
7890
g_object_ref_sink(PGObject(StyleObject^.Owner));
7893
// Put style widget on style window, so that it can be realized.
7819
7894
if AddToStyleWindow then
7821
7896
gtk_widget_show_all(StyleObject^.Widget);
7822
7897
if GtkWidgetIsA(StyleObject^.Widget,GTK_TYPE_MENU) then
7824
// attach menu to window
7825
gtk_menu_attach_to_widget(PGtkMenu(StyleObject^.Widget),
7826
GetStyleWidget(lgsWindow), nil);
7899
// Do nothing. Don't need to attach it to a widget to get the style.
7829
7902
if GtkWidgetIsA(StyleObject^.Widget,GTK_TYPE_MENU_BAR) then
7885
7949
if not GtkWidgetIsA(StyleObject^.Widget,GTK_WINDOW_GET_TYPE) then begin
7886
7950
//DebugLn(['GetStyleWithName realizing ...']);
7887
7951
gtk_widget_realize(StyleObject^.Widget);
7952
//treeview columns must be added after realize otherwise they will have invalid styles
7953
if lgs = lgsTreeView then
7955
gtk_tree_view_append_column(PGtkTreeView(StyleObject^.Widget), gtk_tree_view_column_new);
7956
gtk_tree_view_append_column(PGtkTreeView(StyleObject^.Widget), gtk_tree_view_column_new);
7957
gtk_tree_view_append_column(PGtkTreeView(StyleObject^.Widget), gtk_tree_view_column_new);
7888
7959
//DebugLn('AddToStyleWindow realized: ',WName,' ',GetWidgetDebugReport(StyleObject^.Widget));
7890
7961
ResizeWidget(StyleObject^.Widget,200,200);
8061
8132
Style: PGTKStyle;
8063
8134
Pixmap: PGDKPixmap;
8064
SysColor: TColorRef;
8065
BaseColor: TColorRef;
8066
8136
Red, Green, Blue: byte;
8068
8138
// Set defaults in case something goes wrong
8069
FillChar(Result, SizeOf(Result), 0);
8139
FillChar(Result{%H-}, SizeOf(Result), 0);
8074
SysColor := ColorToRGB(Color);
8075
8144
Result.Fill := GDK_Solid;
8076
RedGreenBlue(TColor(SysColor), Red, Green, Blue);
8145
RedGreenBlue(ColorToRGB(TColor(Color)), Red, Green, Blue);
8077
8146
Result.foreground.Red:=gushort(Red) shl 8 + Red;
8078
8147
Result.foreground.Green:=gushort(Green) shl 8 + Green;
8079
8148
Result.foreground.Blue:=gushort(Blue) shl 8 + Blue;
8599
8669
if Assigned(Style) then
8600
gtk_paint_flat_box(style, drawable, state, shadow, nil, widget,
8670
gtk_paint_flat_box(style, drawable, state, shadow, AClipArea, widget,
8601
8671
detail, x, y, width, height)
8603
8673
gdk_draw_rectangle(drawable, GC, 1, x, y, width, height);