Gtk2: postpone SetSelStart() since selStart can be changed in OnChange event. fixes #16678

git-svn-id: trunk@26253 -
This commit is contained in:
zeljko 2010-06-22 11:55:23 +00:00
parent 98be23e127
commit 00475aa337
3 changed files with 32 additions and 2 deletions

View File

@ -410,6 +410,7 @@ var
GStart, GEnd: gint; GStart, GEnd: gint;
Info: PWidgetInfo; Info: PWidgetInfo;
EntryText: PgChar; EntryText: PgChar;
NeedCursorCheck: Boolean;
begin begin
Result := CallBackDefaultReturn; Result := CallBackDefaultReturn;
@ -417,7 +418,7 @@ begin
{$IFDEF EventTrace} {$IFDEF EventTrace}
EventTrace('changed_editbox', data); EventTrace('changed_editbox', data);
{$ENDIF} {$ENDIF}
NeedCursorCheck := False;
if GTK_IS_ENTRY(Widget) then if GTK_IS_ENTRY(Widget) then
begin begin
{cheat GtkEditable to update cursor pos in gtkEntry. issue #7243} {cheat GtkEditable to update cursor pos in gtkEntry. issue #7243}
@ -431,12 +432,22 @@ begin
if wwiInvalidEvent in Info^.Flags then if wwiInvalidEvent in Info^.Flags then
exclude(Info^.Flags, wwiInvalidEvent) exclude(Info^.Flags, wwiInvalidEvent)
else else
begin
// if we change selstart in OnChange event new cursor pos need to
// be postponed in TGtk2WSCustomEdit.SetSelStart
NeedCursorCheck := True;
gtk_editable_set_position(PGtkEditable(Widget), GStart + 1); gtk_editable_set_position(PGtkEditable(Widget), GStart + 1);
end;
end; end;
end; end;
if NeedCursorCheck then
LockOnChange(PgtkObject(Widget), +1);
FillByte(Mess,SizeOf(Mess),0); FillByte(Mess,SizeOf(Mess),0);
Mess.Msg := CM_TEXTCHANGED; Mess.Msg := CM_TEXTCHANGED;
DeliverMessage(Data, Mess); DeliverMessage(Data, Mess);
if NeedCursorCheck then
LockOnChange(PgtkObject(Widget), -1);
end; end;
function gtkchanged_spinbox(widget: PGtkWidget; data: gPointer): GBoolean; cdecl; function gtkchanged_spinbox(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;

View File

@ -463,6 +463,7 @@ type
ExStyle: Integer; ExStyle: Integer;
EventMask: TGdkEventMask; EventMask: TGdkEventMask;
DoubleBuffer: PGdkPixmap; DoubleBuffer: PGdkPixmap;
CursorPos: integer; // needed for delayed SetSelStart
ControlCursor: HCursor; // current widget cursor ControlCursor: HCursor; // current widget cursor
DefaultCursor: HCursor; // default widget cursor DefaultCursor: HCursor; // default widget cursor
Flags: TWidgetInfoFlags; Flags: TWidgetInfoFlags;

View File

@ -1142,11 +1142,22 @@ begin
gtk_editable_set_editable(PGtkEditable(Widget), not NewReadOnly); gtk_editable_set_editable(PGtkEditable(Widget), not NewReadOnly);
end; end;
function gtk2WSDelayedSelStart(Data: Pointer): gboolean; cdecl;
var
Entry: PGtkEntry;
begin
Result := False;
Entry := PGtkEntry(PWidgetInfo(Data)^.CoreWidget);
gtk_editable_set_position(PGtkEditable(Entry), PWidgetInfo(Data)^.CursorPos);
g_idle_remove_by_data(Data);
end;
class procedure TGtk2WSCustomEdit.SetSelStart(const ACustomEdit: TCustomEdit; class procedure TGtk2WSCustomEdit.SetSelStart(const ACustomEdit: TCustomEdit;
NewStart: integer); NewStart: integer);
var var
NewPos: Integer; NewPos: Integer;
Entry: PGtkEntry; Entry: PGtkEntry;
WidgetInfo: PWidgetInfo;
begin begin
if not WSCheckHandleAllocated(ACustomEdit, 'SetSelStart') then if not WSCheckHandleAllocated(ACustomEdit, 'SetSelStart') then
Exit; Exit;
@ -1157,7 +1168,14 @@ begin
NewPos := Min(NewStart, Entry^.text_max_length) NewPos := Min(NewStart, Entry^.text_max_length)
else else
NewPos := Min(NewStart, Entry^.text_length); NewPos := Min(NewStart, Entry^.text_length);
gtk_entry_set_position(Entry, NewPos); if LockOnChange(PgtkObject(Entry),0) > 0 then
begin
WidgetInfo := GetWidgetInfo(Entry);
WidgetInfo^.CursorPos := NewPos;
// postpone
g_idle_add(@gtk2WSDelayedSelStart, WidgetInfo);
end else
gtk_editable_set_position(PGtkEditable(Entry), NewPos);
end; end;
class procedure TGtk2WSCustomEdit.SetSelLength( class procedure TGtk2WSCustomEdit.SetSelLength(