From ec59292d9e2646776e6247db12cae66536d0be4f Mon Sep 17 00:00:00 2001 From: zeljan1 Date: Tue, 28 Jan 2025 22:42:50 +0100 Subject: [PATCH] Gtk3: Fixed PGtkComboBoxPrivate layout, fixed items painting and sizing of combobox according to the new updated private class. --- lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas | 54 ++-- lcl/interfaces/gtk3/gtk3cellrenderer.pas | 258 ++++++++++++++++++- lcl/interfaces/gtk3/gtk3lclcombobox.inc | 70 ++++- lcl/interfaces/gtk3/gtk3procs.pas | 19 ++ lcl/interfaces/gtk3/gtk3widgets.pas | 13 +- 5 files changed, 370 insertions(+), 44 deletions(-) diff --git a/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas b/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas index 8cb900caa8..d1d5dd78de 100644 --- a/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas +++ b/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas @@ -5810,7 +5810,7 @@ type PPGtkTreeRowReference = ^PGtkTreeRowReference; PGtkTreeRowReference = ^TGtkTreeRowReference; - TGtkComboBoxPrivate = record + TGtkComboBoxPrivate = record //IMPORTANT NOTE: This record is Gtk3-3.24 compatibile only.Code that relies on this record won't work with earlier gtk3 versions !} model: PGtkTreeModel; area: PGtkCellArea; @@ -5819,7 +5819,6 @@ type row_column: gint; wrap_width: gint; - shadow_type: TGtkShadowType; active: gint; // Only temporary active_row: PGtkTreeRowReference; @@ -5827,55 +5826,48 @@ type tree_view: PGtkWidget; cell_view: PGtkWidget; - cell_view_frame: PGtkWidget; - button: PGtkWidget; box: PGtkWidget; + button: PGtkWidget; arrow: PGtkWidget; - separator: PGtkWidget; popup_widget: PGtkWidget; popup_window: PGtkWidget; scrolled_window: PGtkWidget; - inserted_id: gulong; - deleted_id: gulong; - reordered_id: gulong; - changed_id: gulong; + gadget: gPointer; //PGtkCssGadget since 3.22. Hope that gPointer will suffice here. + popup_idle_id: guint; - activate_button: guint; - activate_time: guint32; + trigger_event: PGdkEvent; scroll_timer: guint; resize_idle_id: guint; (*For "has-entry" specific behavior we track * an automated cell renderer and text column *) - text_column: gint; - text_renderer: PGtkCellRenderer; + text_column: gint; + text_renderer: PGtkCellRenderer; - id_column: gint; + id_column: gint; - popup_in_progress: guint; - popup_shown: guint; - add_tearoffs: guint; - has_frame: guint; - is_cell_renderer: guint; - editing_canceled: guint; - auto_scroll: guint; - focus_on_click: guint; - button_sensitivity: guint; - has_entry: guint; - popup_fixed_width: guint; + popup_in_progress: guint; + popup_shown: guint; + add_tearoffs: guint; + has_frame: guint; + is_cell_renderer: guint; + editing_canceled: guint; + auto_scroll: guint; + button_sensitivity: guint; + has_entry: guint; + popup_fixed_width: guint; - row_separator_func: TGtkTreeViewRowSeparatorFunc; - row_separator_data: gpointer; - row_separator_destroy: TGDestroyNotify; + row_separator_func: TGtkTreeViewRowSeparatorFunc; + row_separator_data: gpointer; + row_separator_destroy: TGDestroyNotify; - grab_pointer: PGdkDevice; - grab_keyboard: PGdkDevice; + grab_pointer: PGdkDevice; - tearoff_title: Pgchar; + tearoff_title: Pgchar; end; diff --git a/lcl/interfaces/gtk3/gtk3cellrenderer.pas b/lcl/interfaces/gtk3/gtk3cellrenderer.pas index 4bfdacaa81..ba30075b8d 100644 --- a/lcl/interfaces/gtk3/gtk3cellrenderer.pas +++ b/lcl/interfaces/gtk3/gtk3cellrenderer.pas @@ -26,7 +26,8 @@ interface uses Classes, SysUtils, LCLType, LCLProc, Controls, StdCtrls, ComCtrls, LMessages, - LazGObject2, LazGtk3, LazGdk3, LazGLib2, Gtk3Procs, LazCairo1, LazLogger; + LazGObject2, LazGtk3, LazGdk3, LazGLib2, Gtk3Procs, LazCairo1, + LazPango1, LazLogger; type PLCLIntfCellRenderer = ^TLCLIntfCellRenderer; @@ -189,18 +190,262 @@ begin end; -// get_preferred_width: procedure(cell: PGtkCellRenderer; widget: PGtkWidget; minimum_size: Pgint; natural_size: Pgint); cdecl; +function GetOwnerComboBox(CellView: PGtkCellView): PGtkComboBox; +var + Parent: PGtkWidget; +begin + Result := nil; + + Parent := gtk_widget_get_parent(PGtkWidget(CellView)); + while Assigned(Parent) do + begin + if Gtk3IsComboBox(Parent) then + begin + Result := PGtkComboBox(Parent); + Exit; + end; + Parent := gtk_widget_get_parent(Parent); + end; +end; + +function GTK_IS_CELL_RENDERER_TEXT(cell: PGtkCellRenderer): Boolean; +begin + Result := Assigned(cell) and + (g_type_check_instance_is_a(PGTypeInstance(cell), gtk_cell_renderer_text_get_type)); +end; + +function GetTextFromCellView(widget: PGtkWidget): PgChar; +var + TreeModel: PGtkTreeModel; + Iter: TGtkTreeIter; + Path: PGtkTreePath; + Text: Pgchar; + ColumnIndex: Integer; +begin + Result := nil; + TreeModel := gtk_cell_view_get_model(PGtkCellView(Widget)); + if Assigned(TreeModel) then + begin + Path := gtk_cell_view_get_displayed_row(PGtkCellView(Widget)); + if Assigned(Path) then + begin + if gtk_tree_model_get_iter(TreeModel, @Iter, Path) then + begin + ColumnIndex := 0; + gtk_tree_model_get(TreeModel, @Iter, [ColumnIndex, @Text, -1]); + + if Assigned(Text) then + Result := Text; //result must be freed. + end; + gtk_tree_path_free(Path); + end; + end; +end; + +{$IFDEF GTK3DEBUGCELLRENDERER} +procedure InspectStyleContext(aWidget: PGtkWidget); +var + ABorder: TGtkBorder; + AStyle: PGtkStyleContext; +begin + writeln('==== begin border,margin and padding for ',G_OBJECT_TYPE_NAME(aWidget)); + AStyle := gtk_widget_get_style_context(aWidget); + AStyle^.get_border(GTK_STATE_FLAG_NORMAL, @ABorder); + with Aborder do + writeln(' BORDER CONTEXT L=',left,' T=',top,' R=',right,' B=',Bottom); + AStyle^.get_margin(GTK_STATE_FLAG_NORMAL, @ABorder); + with Aborder do + writeln(' MARGIN CONTEXT L=',left,' T=',top,' R=',right,' B=',Bottom); + AStyle^.get_padding(GTK_STATE_FLAG_NORMAL, @ABorder); + with Aborder do + writeln(' PADDING CONTEXT L=',left,' T=',top,' R=',right,' B=',Bottom); + writeln('=== end ',G_OBJECT_TYPE_NAME(aWidget),' allocated W=',aWidget^.get_allocated_width,' H=',aWidget^.get_allocated_height); +end; +{$ENDIF} + +function CreatePangoLayoutFromCellRendererText(cell: PGtkCellRendererText; widget: PGtkCellView): PPangoLayout; +var + layout: PPangoLayout; + APangoContext: PPangoContext; + gvalue: TGValue; + text: Pgchar; + alignment: TPangoAlignment; + fontDescription: PPangoFontDescription; + attributes: PPangoAttrList; +begin + Result := nil; + + if not Assigned(cell) or not Assigned(widget) then + exit; + + APangoContext := widget^.get_pango_context; + if not Assigned(APangoContext) then + exit; + + layout := pango_layout_new(APangoContext); + if not Assigned(layout) then + exit; + + FillChar(gvalue{%H-}, SizeOf(gvalue), 0); + + g_value_init(@gvalue, G_TYPE_STRING); + g_object_get_property(PGObject(cell), 'text', @gvalue); + text := g_value_get_string(@gvalue); + if Assigned(text) then + pango_layout_set_text(layout, text, -1); + g_value_unset(@gvalue); + + g_value_init(@gvalue, G_TYPE_ENUM); + g_object_get_property(PGObject(cell), 'alignment', @gvalue); + alignment := TPangoAlignment(g_value_get_enum(@gvalue)); + pango_layout_set_alignment(layout, alignment); + g_value_unset(@gvalue); + + fontDescription := gtk_widget_get_pango_context(widget)^.get_font_description; + + if Assigned(fontDescription) then + pango_layout_set_font_description(layout, fontDescription); + + Result := layout; +end; + procedure LCLIntfCellRenderer_GetPreferredWidth(cell: PGtkCellRenderer; widget: PGtkWidget; minimum_size: Pgint; natural_size: Pgint); cdecl; var CellClass: PLCLIntfCellRendererClass; + AWidget: TGtk3Widget; + W, xpad, ypad: gint; + Alloc: TGtkAllocation; + ACombo: PGtkComboBox; + APangoContext: PPangoContext; + APangoLayout: PPangoLayout; + APangoText: Pgchar; + APangoWidth, APangoHeight: gint; + ABorder, AMargin, APadding: TGtkBorder; begin {$IFDEF GTK3DEBUGCELLRENDERER} DebugLn('*** LCLIntfCellRenderer_GetPreferredWidth ***'); {$ENDIF} + CellClass := PLCLIntfCellRendererClass(cell^.g_type_instance.g_class); CellClass^.DefaultGetPreferredWidth(cell, widget, minimum_size, natural_size); + + ACombo := GetOwnerComboBox(PGtkCellView(widget)); + if ACombo = nil then + exit; + AWidget := TGtk3Widget(HwndFromGtkWidget(aCombo)); + + W := 0; // width of button area + + if not Assigned(aWidget) then + begin + {$IFDEF GTK3DEBUGCELLRENDERER} + writeln('********** warning TGtk3Widget not assigned ! **************** Widget=',G_OBJECT_TYPE_NAME(widget)); + {$ENDIF} + exit; + end; + if not Assigned(aWidget.LCLObject) then + begin + {$IFDEF GTK3DEBUGCELLRENDERER} + writeln('********* warning LCLObject not assigned ! ***************'); + {$ENDIF} + exit; + end; + + if not aWidget.WidgetMapped then + exit; // there's no reason to recalculate size while widget isn't mapped yet, triggers too many times. + + if Assigned(ACombo) then + begin + {$IFDEF GTK3DEBUGCELLRENDERER} + writeln('Widget is ',G_OBJECT_TYPE_NAME(widget),' ',G_OBJECT_TYPE_NAME(ACombo),' LCL=',dbgsName(aWidget.LCLObject)); + InspectStyleContext(aCombo); + {$ENDIF} + + //button contains borders,margins and padding + if TGtk3ComboBox(aWidget).GetButtonWidget <> nil then + begin + TGtk3ComboBox(aWidget).GetButtonWidget^.realize; + {$IFDEF GTK3DEBUGCELLRENDERER} + InspectStyleContext(TGtk3ComboBox(aWidget).GetButtonWidget); + {$ENDIF} + GetStyleContextSizes(TGtk3ComboBox(aWidget).GetButtonWidget, ABorder, AMargin, APadding, xpad, ypad); + W := ABorder.left + ABorder.right + AMargin.left + AMargin.Right + APadding.left + APadding.Right; + end; + + //button area size is button borders,margins and padding + allocated width of arrow (GtkIcon) + if TGtk3ComboBox(aWidget).GetArrowWidget <> nil then + begin + TGtk3ComboBox(aWidget).GetArrowWidget^.get_allocation(@Alloc); + //PROBLEM: when combo parent form modal window arrow returns width 1 :(, widget is mapped,realized and visible, so how it's possible + if GTK_IS_CELL_RENDERER_TEXT(cell) and (Alloc.width <= 1) then + begin + // This combo won't be shown as expected, usually happens with combos on modal windows or frames parented to modal win. + {$warning fix this case, maybe alloc primitive combobox when creating widgetset with other widgets for GetSystemMetrics. We need accurate button area width} + Alloc.width := 11; + end; + W := W + Alloc.width; + {$IFDEF GTK3DEBUGCELLRENDERER} + InspectStyleContext(TGtk3ComboBox(aWidget).GetArrowWidget); + {$ENDIF} + end; + {$IFDEF GTK3DEBUGCELLRENDERER} + ACombo^.get_allocation(@Alloc); + writeln('== ComboBox allocation w=',Alloc.width,' alloc ',dbgs(RectFromGdkRect(Alloc)),' Current W=',W); + {$ENDIF} + + end else + begin + {$IFDEF GTK3DEBUGCELLRENDERER} + writeln('Error: ************** cannot get combobox, expect crash ! ****************'); + {$ENDIF} + end; + + if GTK_IS_CELL_RENDERER_TEXT(cell) then + begin + APangoText := GetTextFromCellView(widget); + APangoLayout := pango_layout_new(gtk_widget_get_pango_context(Widget)); + + if Assigned(APangoLayout) then + begin + pango_layout_set_spacing(APangoLayout, 2); + if APangoText = nil then + pango_layout_set_text(APangoLayout, 'Wj' , -1) + else + pango_layout_set_text(APangoLayout, APangoText , -1); + pango_layout_set_ellipsize(APangoLayout, PANGO_ELLIPSIZE_END); + if APangoText <> nil then + g_free(APangoText); + + pango_layout_get_size(APangoLayout, @APangoWidth, @APangoHeight); + + APangoWidth := APangoWidth div PANGO_SCALE; + APangoHeight := APangoHeight div PANGO_SCALE; + + cell^.get_padding(@xpad, @ypad); + + g_object_unref(APangoLayout); + + if Assigned(minimum_size) then + minimum_size^ := aWidget.LCLObject.Width - W - xpad; + if Assigned(natural_size) then + natural_size^ := aWidget.LCLObject.Width - W - xpad; + + //sometimes only way to have properly sized and painted csDropDownList and owner drawn for combos on modal windows. + //leave this commented code here, I need it for testing various cases. + //if TComboBox(aWidget.LCLObject).Style = csDropDownList then + // cell^.set_fixed_size(aWidget.LCLObject.Width - W - xpad, APangoHeight + ypad + ypad + 1); // Min(APangoHeight - ypad, AWidget.LCLObject.Height - ypad)); + //cell^.set_alignment(0, 0); + //cell^.set_padding(2, 0); + end; + + end else + DebugLn('BUG: LCLIntfCellRenderer_GetPreferredWidth() cell is not PGtkCellRendererText !'); + {$IFDEF GTK3DEBUGCELLRENDERER} - // DebugLn('*** LCLIntfCellRenderer_GetPreferredWidth MIN=',dbgs(minimum_size^),' naturalw=',dbgs(natural_size^)); + if (minimum_size = nil) or (natural_size =nil) then + writeln('*** LCLIntfCellRenderer_GetPreferredWidth defaultGetPreferredWidth have assigned minimum_size=',Assigned(minimum_size),' natural_size=',Assigned(natural_size)) + else + writeln('*** LCLIntfCellRenderer_GetPreferredWidth MIN=',dbgs(minimum_size^),' naturalw=',dbgs(natural_size^)); {$ENDIF} end; @@ -214,7 +459,6 @@ begin {$ENDIF} CellClass := PLCLIntfCellRendererClass(cell^.g_type_instance.g_class); CellClass^.DefaultGetPreferredHeight(cell, widget, minimum_size, natural_size); - end; procedure LCLIntfCellRenderer_GetPreferredWidthForHeight(cell: PGtkCellRenderer; widget: PGtkWidget; @@ -688,12 +932,14 @@ begin not (TCustomComboBox(TGtk3Widget(Data).LCLObject).Style.HasEditBox) and not (TCustomComboBox(TGtk3Widget(Data).LCLObject).DroppedDown) then begin + (* Value.clear; Value.init(G_TYPE_UINT); Value.set_uint(0); g_object_get_property(PgObject(cell),'ypad',@Value); g_object_set_property(PGObject(cell), 'ypad', @Value); Value.unset; + *) end else if wtListView in TGtk3Widget(Data).WidgetType then begin @@ -723,7 +969,7 @@ begin Value.clear; Value.init(G_TYPE_STRING); - Value.set_string(PgChar(S)); + {%H-}Value.set_string(PgChar(S)); cell^.set_property('text', @Value); Value.unset; end else @@ -743,7 +989,7 @@ begin //Value.data[0].v_pointer := PgChar(S); value.clear; value.init(G_TYPE_STRING); - Value.set_string(PgChar(S)); + {%H-}Value.set_string(PgChar(S)); // set text only if we are not ownerdrawn ! cell^.set_property('text', @Value); Value.unset; diff --git a/lcl/interfaces/gtk3/gtk3lclcombobox.inc b/lcl/interfaces/gtk3/gtk3lclcombobox.inc index 6d3b635285..bd376840cb 100644 --- a/lcl/interfaces/gtk3/gtk3lclcombobox.inc +++ b/lcl/interfaces/gtk3/gtk3lclcombobox.inc @@ -31,7 +31,6 @@ begin DebugLn('Error: LCLGtkComboBoxGetPreferredWidth cannot get ParentClass !'); exit; end; - //check what parent class says about minimum and natural width. ParentClass^.get_preferred_width(widget, min_width, nat_width); @@ -58,6 +57,12 @@ procedure LCLGtkComboBoxGetPreferredHeight(widget: PGtkWidget; min_height, nat_h var AControl:TGtk3Widget; ParentClass:PGtkWidgetClass; + ACombo: PGtkComboBox; + aContext: PPangoContext; + aPangoLayout: PPangoLayout; + ABorder, AMargin, APadding: TGtkBorder; + w, h, xpad, ypad: gint; + aList: PGList; begin if not Assigned(min_height) or not Assigned(nat_height) then @@ -91,7 +96,36 @@ begin end; if AControl.LCLObject.AutoSize then + begin + //seem that gtk is off by 1 pixel, csDropDown and csDropDownList should have same height' + //writeln('==============>',dbgsName(AControl.LCLObject),' preferred height=',min_height^, ' nat=',nat_height^); + if not (TCustomComboBox(AControl.LCLObject).Style in [csDropDown, csSimple]) then + begin + aCombo := PGtkComboBox(widget); + + aList := PGtkCellLayout(aCombo)^.get_cells; + xpad := 0; + ypad := 0; + if aList = nil then + exit; + PGtkCellRenderer(aList[0].data)^.get_padding(@xpad, @ypad); + g_free(aList); + + GetStyleContextSizes(aCombo^.priv3^.button, ABorder, AMargin, APadding, w, h); + aContext := PGtkCellView(ACombo^.priv3^.cell_view)^.get_pango_context; + if aContext = nil then + exit; + aPangoLayout := pango_layout_new(aContext); + aPangoLayout^.set_text('Wj', -1); + aPangoLayout^.get_size(@w, @h); + w := w div PANGO_SCALE; + h := (h div PANGO_SCALE) + 1; + min_height^ := h + ABorder.Top + ABorder.Bottom + AMargin.Top + AMargin.Bottom + APadding.Top + APadding.Bottom + (ypad * 2); + if Assigned(nat_height) then + nat_height^ := min_height^; + end; exit; // keep gtk calculated height. + end; if AControl.LCLHeight = 0 then begin @@ -104,6 +138,39 @@ begin end; end; +{$IFDEF GTK3DEBUGCOMBOBOX} +function LCLGtkComboBoxDraw(widget: PGtkWidget; cairo: Pcairo_t): gboolean; cdecl; +var + ParentClass: PGtkWidgetClass; + Alloc: TGtkAllocation; + ARect, AreaRect: TGdkRectangle; + dx, dy, dw, dh: Double; + Layout: PPangoLayout; + aText: Pgchar; + APangoContext: PPangoContext; + aArea: PGtkCellArea; + column: PGtkTreeViewColumn; +begin + //PLAYGROUND ONLY ! + widget^.get_allocation(@Alloc); + + //APangoContext := gtk_widget_get_pango_context(Widget); + + gdk_cairo_get_clip_rectangle(cairo, @ARect); + //cairo_get_current_point(cairo, @dx, @dy); + cairo_clip_extents(cairo, @dx, @dy, @dw, @dh); + //aRegion := gdk_cairo_get_drawing_context(cairo)^.get_clip; + ParentClass := PGtkWidgetClass(g_type_class_peek_parent(widget^.g_type_instance.g_class)); + //cairo_translate(cairo, -dx, -dy); + writeln('Overriden comboBox draw ...',dbgs(RectFromGdkRect(Alloc)),' ClipRect=',dbgs(RectFromGdkRect(ARect)),' CurrX=',dbgs(dx),' Y=',dbgs(dy),' W=',dbgs(dw),' H=',dbgs(dh)); + Result := ParentClass^.draw(widget, cairo); + + cairo_user_to_device(cairo, @dx, @dy); + cairo_user_to_device(cairo, @dw, @dh); + writeln('Cairo to device dx=',dbgs(dx),' dy=',dbgs(dy),' dw=',dbgs(dw-dx),' dh=',dbgs(dh-dy)); +end; +{$ENDIF} + procedure LCLGtkComboBoxClassInit(klass: PGTypeClass; data: Pointer); cdecl; {$IFDEF GTK3DEBUGCOMBOBOX} procedure WalkTypeHierarchy(klass: PGTypeClass); @@ -122,6 +189,7 @@ begin AWidgetClass^.get_preferred_width := @LCLGtkComboBoxGetPreferredWidth; AWidgetClass^.get_preferred_height := @LCLGtkComboBoxGetPreferredHeight; {$IFDEF GTK3DEBUGCOMBOBOX} + AWidgetClass^.draw := @LCLGtkComboBoxDraw; //debug - looks ok. //WalkTypeHierarchy(klass); WalkParentClassHierarchy(klass); diff --git a/lcl/interfaces/gtk3/gtk3procs.pas b/lcl/interfaces/gtk3/gtk3procs.pas index 69961b325f..10e97b6420 100644 --- a/lcl/interfaces/gtk3/gtk3procs.pas +++ b/lcl/interfaces/gtk3/gtk3procs.pas @@ -317,6 +317,8 @@ procedure SetWindowCursor(AWindow: PGdkWindow; ACursor: HCursor; ARecursive: Boolean; ASetDefault: Boolean); procedure SetGlobalCursor(Cursor: HCURSOR); +function GetStyleContextSizes(awidget: PGtkWidget; out ABorder, AMargin, APadding: TGtkBorder; out AWidth, AHeight: integer): boolean; + type Charsetstr = string[15]; PCharSetEncodingRec=^TCharSetEncodingRec; @@ -1364,4 +1366,21 @@ begin Result := g_type_name(PGObject(AWidget)^.g_type_instance.g_class^.g_type); end; +function GetStyleContextSizes(awidget: PGtkWidget; out ABorder, AMargin, APadding: TGtkBorder; out AWidth, AHeight: integer): boolean; +var + AStyle: PGtkStyleContext; +begin + Result := False; + ABorder := Default(TGtkBorder); + AMargin := Default(TGtkBorder); + APadding := Default(TGtkBorder); + AStyle := gtk_widget_get_style_context(aWidget); + AWidth := aWidget^.get_allocated_width; + AHeight := aWidget^.get_allocated_height; + AStyle^.get_border(GTK_STATE_FLAG_NORMAL, @ABorder); + AStyle^.get_margin(GTK_STATE_FLAG_NORMAL, @AMargin); + AStyle^.get_padding(GTK_STATE_FLAG_NORMAL, @APadding); + Result := True; +end; + end. diff --git a/lcl/interfaces/gtk3/gtk3widgets.pas b/lcl/interfaces/gtk3/gtk3widgets.pas index 644b3798ca..9671c29e69 100644 --- a/lcl/interfaces/gtk3/gtk3widgets.pas +++ b/lcl/interfaces/gtk3/gtk3widgets.pas @@ -729,7 +729,7 @@ type function GetCellView: PGtkCellView; function GetPopupWidget: PGtkWidget; function GetButtonWidget: PGtkWidget; - function GetCellViewFrame: PGtkWidget; + function GetArrowWidget: PGtkWidget; procedure InitializeWidget; override; property DroppedDown: boolean read GetDroppedDown write SetDroppedDown; property ItemIndex: Integer read GetItemIndex write SetItemIndex; @@ -5052,7 +5052,7 @@ var ACurrentPage: gint; begin Result := False; - AWidget := AData; + AWidget := PGtkNoteBook(AData); if not Gtk3IsWidget(AWidget) then exit; if g_object_get_data(AWidget,'switch-page-signal-stopped') <> nil then @@ -7584,20 +7584,21 @@ begin Result := nil; if not IsWidgetOk then exit; + // button is of type GtkToggleButton if PGtkComboBox(GetContainerWidget)^.priv3^.button <> nil then Result := PGtkComboBox(GetContainerWidget)^.priv3^.button; end; -function TGtk3ComboBox.GetCellViewFrame: PGtkWidget; +function TGtk3ComboBox.GetArrowWidget: PGtkWidget; begin Result := nil; if not IsWidgetOk then exit; - if PGtkComboBox(GetContainerWidget)^.priv3^.cell_view_frame <> nil then - Result := PGtkComboBox(GetContainerWidget)^.priv3^.cell_view_frame; + // arrow is type is GtkIcon + if PGtkComboBox(GetContainerWidget)^.priv3^.arrow <> nil then + Result := PGtkComboBox(GetContainerWidget)^.priv3^.arrow; end; - function TGtk3ComboBox.CreateWidget(const Params: TCreateParams): PGtkWidget; var ACombo: TCustomComboBox;