View Issue Details

IDProjectCategoryView StatusLast Update
0014728LazarusLCLpublic2014-07-11 13:53
ReporterFabio Luis GirardiAssigned ToJuha Manninen 
PrioritynormalSeveritytweakReproducibilityalways
Status closedResolutionfixed 
Platformx64OSLinuxOS Version2.6
Product Version0.9.29 (SVN)Product Buildr22029 
Target VersionFixed in Version0.9.31 (SVN) 
Summary0014728: ScrollCode=scEndScroll not appears at the end of scroll
DescriptionUnder GTK2 and QT, the ScrollCode=scEndScroll is not fired, like under windows. Others codes is fired equals in both widgetsets.
TagsNo tags attached.
Fixed in Revisionr31447, 31483
LazTarget0.99.0
WidgetsetGTK 2, QT
Attached Files
  • scrollcode_test.zip (2,725 bytes)
  • scrollcodes.diff (5,646 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31416)
    +++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
    @@ -6230,7 +6230,15 @@
       SliderAction := SliderActions[Action];
     
       case SliderAction of
    -    QAbstractSliderSliderNoAction: Exit;
    +    QAbstractSliderSliderNoAction:
    +    begin
    +      if getTracking and getSliderDown then
    +      begin
    +        LMScroll.ScrollCode := SB_THUMBPOSITION;
    +        DeliverMessage(LMScroll);
    +      end;
    +    LMScroll.ScrollCode := SB_ENDSCROLL;
    +    end;
         QAbstractSliderSliderSingleStepAdd:
           begin
             if LMScroll.Msg = LM_HSCROLL then
    @@ -6273,15 +6281,8 @@
             else
               LMScroll.ScrollCode := SB_BOTTOM;
           end;
    -    QAbstractSliderSliderMove:
    -      begin
    -        if getTracking and getSliderDown then
    -          LMScroll.ScrollCode := SB_THUMBTRACK
    -        else
    -          LMScroll.ScrollCode := SB_THUMBPOSITION;
    -      end;
    +    QAbstractSliderSliderMove: LMScroll.ScrollCode := SB_THUMBTRACK;
       end;
    -
       DeliverMessage(LMScroll);
     end;
     
    @@ -6352,7 +6353,16 @@
             Result := inherited EventFilter(Sender, Event)
           else
             Result := False;
    +      if QEvent_type(Event) = QEventKeyRelease  then
    +      QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                        QAbstractSliderSliderNoAction);
         end;
    +    QEventMouseButtonPress:
    +    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                        QAbstractSliderSliderMove);
    +    QEventMouseButtonRelease:
    +    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                        QAbstractSliderSliderNoAction);
       else
         if FOwnWidget then
           Result := inherited EventFilter(Sender, Event);
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
    @@ -2698,8 +2699,46 @@
         ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
       end;
       Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
    +
    +  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) then exit;
    +
    +  if Msg.Scrollcode=SB_THUMBTRACK then
    +  begin
    +    if PGTKWidget(ARange)^.state = 0 then
    +    begin
    +      Msg.ScrollCode := SB_THUMBPOSITION;
    +      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    +      Msg.ScrollCode:=SB_ENDSCROLL;
    +      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    +    end;
    +    PGTKWidget(Arange)^.state:=2;
    +  end
    +  else PGTKWidget(Arange)^.state:=1;
     end;
     
    +function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +begin
    +  Widget^.state:=2;
    +  Result:=False;
    +end;
    +
    +function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +var
    +  Avalue: gdouble;
    +  WidgetInfo: PWidgetInfo;
    +begin
    +  AValue:=PGtkRange(Widget)^.adjustment^.value;
    +  WidgetInfo:=GetWidgetInfo(Widget, false);
    +
    +  if Assigned(WidgetInfo) and (Widget^.state=1) then
    +  Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    +
    +  Widget^.state:=0;
    +  Result:=False;
    +end;
    +
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
     var
       Msg: TLMVScroll;
    Index: lcl/interfaces/gtk2/gtk2proc.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.pp	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2proc.pp	(copia de trabajo)
    @@ -206,6 +206,10 @@
     // PGtkRange cb
     function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
       AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
    +function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
       AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
     function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
    Index: lcl/interfaces/gtk2/gtk2proc.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
    @@ -377,7 +377,7 @@
     begin
       case ScrollType of
           GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
    -      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
    +      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
           GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
           GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
           GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
    Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
    @@ -2430,6 +2430,11 @@
       TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
       
       g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
    +  g_signal_connect(AGtkWidget, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
    +  g_signal_connect(AGtkWidget, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
    +
     end;
     
     class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl;
    
    scrollcodes.diff (5,646 bytes)
  • scrollcodes2.diff (5,503 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31416)
    +++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
    @@ -6230,7 +6230,15 @@
       SliderAction := SliderActions[Action];
     
       case SliderAction of
    -    QAbstractSliderSliderNoAction: Exit;
    +    QAbstractSliderSliderNoAction:
    +    begin
    +      if getTracking and getSliderDown then
    +      begin
    +        LMScroll.ScrollCode := SB_THUMBPOSITION;
    +        DeliverMessage(LMScroll);
    +      end;
    +    LMScroll.ScrollCode := SB_ENDSCROLL;
    +    end;
         QAbstractSliderSliderSingleStepAdd:
           begin
             if LMScroll.Msg = LM_HSCROLL then
    @@ -6273,15 +6281,8 @@
             else
               LMScroll.ScrollCode := SB_BOTTOM;
           end;
    -    QAbstractSliderSliderMove:
    -      begin
    -        if getTracking and getSliderDown then
    -          LMScroll.ScrollCode := SB_THUMBTRACK
    -        else
    -          LMScroll.ScrollCode := SB_THUMBPOSITION;
    -      end;
    +    QAbstractSliderSliderMove: LMScroll.ScrollCode := SB_THUMBTRACK;
       end;
    -
       DeliverMessage(LMScroll);
     end;
     
    @@ -6352,7 +6353,13 @@
             Result := inherited EventFilter(Sender, Event)
           else
             Result := False;
    +      if QEvent_type(Event) = QEventKeyRelease  then
    +      QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                        QAbstractSliderSliderNoAction);
         end;
    +    QEventMouseButtonRelease:
    +    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                        QAbstractSliderSliderNoAction);
       else
         if FOwnWidget then
           Result := inherited EventFilter(Sender, Event);
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
    @@ -2698,8 +2699,46 @@
         ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
       end;
       Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
    +
    +  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) then exit;
    +
    +  if Msg.Scrollcode=SB_THUMBTRACK then
    +  begin
    +    if PGTKWidget(ARange)^.state = 0 then
    +    begin
    +      Msg.ScrollCode := SB_THUMBPOSITION;
    +      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    +      Msg.ScrollCode:=SB_ENDSCROLL;
    +      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    +    end;
    +    PGTKWidget(Arange)^.state:=2;
    +  end
    +  else PGTKWidget(Arange)^.state:=1;
     end;
     
    +function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +begin
    +  Widget^.state:=2;
    +  Result:=False;
    +end;
    +
    +function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +var
    +  Avalue: gdouble;
    +  WidgetInfo: PWidgetInfo;
    +begin
    +  AValue:=PGtkRange(Widget)^.adjustment^.value;
    +  WidgetInfo:=GetWidgetInfo(Widget, false);
    +
    +  if Assigned(WidgetInfo) and (Widget^.state=1) then
    +  Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    +
    +  Widget^.state:=0;
    +  Result:=False;
    +end;
    +
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
     var
       Msg: TLMVScroll;
    Index: lcl/interfaces/gtk2/gtk2proc.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.pp	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2proc.pp	(copia de trabajo)
    @@ -206,6 +206,10 @@
     // PGtkRange cb
     function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
       AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
    +function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
       AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
     function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
    Index: lcl/interfaces/gtk2/gtk2proc.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
    @@ -377,7 +377,7 @@
     begin
       case ScrollType of
           GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
    -      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
    +      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
           GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
           GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
           GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
    Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
    @@ -2430,6 +2430,11 @@
       TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
       
       g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
    +  g_signal_connect(AGtkWidget, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
    +  g_signal_connect(AGtkWidget, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
    +
     end;
     
     class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl;
    
    scrollcodes2.diff (5,503 bytes)
  • scrollcodes3.diff (6,705 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31416)
    +++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
    @@ -6230,7 +6230,15 @@
       SliderAction := SliderActions[Action];
     
       case SliderAction of
    -    QAbstractSliderSliderNoAction: Exit;
    +    QAbstractSliderSliderNoAction:
    +    begin
    +      if getTracking and getSliderDown then
    +      begin
    +        LMScroll.ScrollCode := SB_THUMBPOSITION;
    +        DeliverMessage(LMScroll);
    +      end;
    +    LMScroll.ScrollCode := SB_ENDSCROLL;
    +    end;
         QAbstractSliderSliderSingleStepAdd:
           begin
             if LMScroll.Msg = LM_HSCROLL then
    @@ -6273,13 +6281,7 @@
             else
               LMScroll.ScrollCode := SB_BOTTOM;
           end;
    -    QAbstractSliderSliderMove:
    -      begin
    -        if getTracking and getSliderDown then
    -          LMScroll.ScrollCode := SB_THUMBTRACK
    -        else
    -          LMScroll.ScrollCode := SB_THUMBPOSITION;
    -      end;
    +    QAbstractSliderSliderMove: LMScroll.ScrollCode := SB_THUMBTRACK;
       end;
     
       DeliverMessage(LMScroll);
    @@ -6352,7 +6354,20 @@
             Result := inherited EventFilter(Sender, Event)
           else
             Result := False;
    +      if (QEvent_type(Event) = QEventKeyRelease) and not
    +        (QKeyEvent_isAutoRepeat(QKeyEventH(event))) then
    +        begin
    +          Case QKeyEvent_key(QKeyEventH(Event)) of
    +            QtKey_Left, QtKey_Up, QtKey_Right, QtKey_Down,
    +            QtKey_PageUp, QtKey_PageDown, QtKey_Home, QtKey_End:
    +              QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                       QAbstractSliderSliderNoAction);
    +          end;
    +        end;
         end;
    +    QEventMouseButtonRelease:
    +    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
    +                        QAbstractSliderSliderNoAction);
       else
         if FOwnWidget then
           Result := inherited EventFilter(Sender, Event);
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
    @@ -2664,6 +2665,7 @@
     var
       Msg: TLMVScroll;
       MaxValue: gdouble;
    +  State: PByte;
     begin
       Result := CallBackDefaultReturn;
     
    @@ -2698,8 +2700,58 @@
         ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
       end;
       Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
    +
    +  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) or
    +    not Assigned(AWidgetInfo^.UserData) then exit;
    +
    +  State:=AWidgetInfo^.UserData;
    +
    +  if Msg.Scrollcode=SB_THUMBTRACK then
    +  begin
    +    if State^ = 0 then
    +    begin
    +      Msg.ScrollCode := SB_THUMBPOSITION;
    +      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    +      Msg.ScrollCode:=SB_ENDSCROLL;
    +      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    +    end;
    +  end
    +  else State^:=1;
     end;
     
    +function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +var
    +  State: PByte;
    +  WidgetInfo: PWidgetInfo;
    +begin
    +  WidgetInfo:=GetWidgetInfo(Widget, false);
    +  if Assigned(WidgetInfo^.UserData) then
    +  begin
    +    State:=WidgetInfo^.UserData;
    +    State^:=2;
    +  end;
    +  Result:=False;
    +end;
    +
    +function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +var
    +  Avalue: gdouble;
    +  WidgetInfo: PWidgetInfo;
    +  State: PByte;
    +begin
    +  AValue:=PGtkRange(Widget)^.adjustment^.value;
    +  WidgetInfo:=GetWidgetInfo(Widget, false);
    +  If Assigned(WidgetInfo^.UserData) then
    +  begin
    +    State:=WidgetInfo^.UserData;
    +    if State^=1 then Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    +    State^:=0;
    +  end;
    +  Result:=False;
    +end;
    +
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
     var
       Msg: TLMVScroll;
    Index: lcl/interfaces/gtk2/gtk2proc.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.pp	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2proc.pp	(copia de trabajo)
    @@ -206,6 +206,10 @@
     // PGtkRange cb
     function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
       AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
    +function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    +function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    +  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
       AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
     function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
    Index: lcl/interfaces/gtk2/gtk2proc.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
    @@ -377,7 +377,7 @@
     begin
       case ScrollType of
           GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
    -      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
    +      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
           GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
           GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
           GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
    Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31416)
    +++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
    @@ -2430,6 +2430,10 @@
       TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
       
       g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
    +  g_signal_connect(AGtkWidget, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
    +  g_signal_connect(AGtkWidget, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
     end;
     
     class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl;
    @@ -2438,6 +2442,7 @@
       Adjustment: PGtkAdjustment = nil;
       Widget: PGtkWidget;
       WidgetInfo: PWidgetInfo;
    +  State: PByte;
     begin
       with TScrollBar(AWinControl) do
       begin
    @@ -2458,6 +2463,12 @@
       DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl));
       {$ENDIF}
       WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams);
    +
    +  WidgetInfo^.DataOwner:=True;
    +  State:=New(PByte);
    +  WidgetInfo^.UserData:=State;
    +  State^:=0;
    +
       Set_RC_Name(AWinControl, Widget);
       SetCallbacks(Widget, WidgetInfo);
     end;
    
    scrollcodes3.diff (6,705 bytes)
  • scrolltype.diff (1,559 bytes)
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31457)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
    @@ -2696,6 +2697,11 @@
           SmallPos := High(SmallPos);
     
         ScrollBar := HWND(PtrUInt(ARange));
    +
    +    if (AWidgetInfo^.LCLObject is TScrollBar) and
    +      (ASCrollType = GTK_SCROLL_JUMP) then
    +       AScrollType := -1;
    +
         ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
       end;
       Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
    Index: lcl/interfaces/gtk2/gtk2proc.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31457)
    +++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
    @@ -377,7 +377,7 @@
     begin
       case ScrollType of
           GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
    -      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
    +      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
           GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
           GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
           GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
    @@ -391,7 +391,8 @@
           GTK_SCROLL_PAGE_LEFT     : Result := SB_PAGELEFT;
           GTK_SCROLL_PAGE_RIGHT    : Result := SB_PAGERIGHT;
           GTK_SCROLL_START         : Result := SB_TOP;
    -      GTK_SCROLL_END           : Result := SB_BOTTOM;
    +      GTK_SCROLL_END           : Result := SB_BOTTOM
    +      else Result:=SB_THUMBTRACK;
         end;
     end;
     
    
    
    scrolltype.diff (1,559 bytes)
  • test_scroll.diff (4,762 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31469)
    +++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
    @@ -6196,7 +6196,7 @@
       LMScroll.Pos := p1;
       LMScroll.ScrollCode := SIF_POS;
     
    -  if not InUpdate then
    +  if not InUpdate and not getTracking then
         DeliverMessage(LMScroll);
     
       b := p1 = getMax;
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31469)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
    @@ -2664,10 +2665,11 @@
     var
       Msg: TLMVScroll;
       MaxValue: gdouble;
    -  State: PByte;
    +  Widget: PGTKWidget;
     begin
       Result := CallBackDefaultReturn;
     
    +  Widget:=PGTKWidget(ARange);
       //DebugLn(Format('Trace:[Gtk2RangeScrollCB] Value: %d', [RoundToInt(AValue)]));
       if G_OBJECT_TYPE(ARange) = gtk_hscrollbar_get_type then
         Msg.Msg := LM_HSCROLL
    @@ -2700,14 +2702,9 @@
       end;
       Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
     
    -  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) or
    -    not Assigned(AWidgetInfo^.UserData) then exit;
    -
    -  State:=AWidgetInfo^.UserData;
    -
       if Msg.Scrollcode=SB_THUMBTRACK then
       begin
    -    if State^ = 0 then
    +    if Widget^.state = 0 then
         begin
           Msg.ScrollCode := SB_THUMBPOSITION;
           DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    @@ -2715,22 +2712,14 @@
           DeliverMessage(AWidgetInfo^.LCLObject, Msg);
         end;
       end
    -  else State^:=1;
    +  else Widget^.state := 1;
     end;
     
     function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
       Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    -var
    -  State: PByte;
    -  WidgetInfo: PWidgetInfo;
     begin
    -  WidgetInfo:=GetWidgetInfo(Widget, false);
    -  if Assigned(WidgetInfo^.UserData) then
    -  begin
    -    State:=WidgetInfo^.UserData;
    -    State^:=2;
    -  end;
    -  Result:=False;
    +  Widget^.state := 2;
    +  Result := CallBackDefaultReturn;;
     end;
     
     function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    @@ -2738,17 +2727,15 @@
     var
       Avalue: gdouble;
       WidgetInfo: PWidgetInfo;
    -  State: PByte;
     begin
       AValue:=PGtkRange(Widget)^.adjustment^.value;
    -  WidgetInfo:=GetWidgetInfo(Widget, false);
    -  If Assigned(WidgetInfo^.UserData) then
    -  begin
    -    State:=WidgetInfo^.UserData;
    -    if State^=1 then Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    -    State^:=0;
    -  end;
    -  Result:=False;
    +  WidgetInfo:=GetWidgetInfo(Widget, False);
    +  if not Assigned(WidgetInfo) then
    +    WidgetInfo:=GetWidgetInfo(Widget^.parent, False);
    +  if Assigned(WidgetInfo) and (Widget^.state = 1) then
    +    Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    +  Widget^.state := 0;
    +  Result := CallBackDefaultReturn;
     end;
     
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
    Index: lcl/interfaces/gtk2/gtk2wscontrols.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wscontrols.pp	(revisión: 31469)
    +++ lcl/interfaces/gtk2/gtk2wscontrols.pp	(copia de trabajo)
    @@ -190,6 +190,14 @@
         TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
       g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value',
         TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
    +  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
    +  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
    +    g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
    +  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
     
       g_signal_connect(Widget, 'scroll-event', TGCallback(@Gtk2ScrolledWindowScrollCB), WidgetInfo);
     end;
    Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31469)
    +++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
    @@ -2442,7 +2442,6 @@
       Adjustment: PGtkAdjustment = nil;
       Widget: PGtkWidget;
       WidgetInfo: PWidgetInfo;
    -  State: PByte;
     begin
       with TScrollBar(AWinControl) do
       begin
    @@ -2464,11 +2463,6 @@
       {$ENDIF}
       WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams);
     
    -  WidgetInfo^.DataOwner:=True;
    -  State:=New(PByte);
    -  WidgetInfo^.UserData:=State;
    -  State^:=0;
    -
       Set_RC_Name(AWinControl, Widget);
       SetCallbacks(Widget, WidgetInfo);
     end;
    
    test_scroll.diff (4,762 bytes)
  • scrollbartester.tar.gz (3,579 bytes)
  • test_scroll2.diff (5,275 bytes)
    Index: lcl/interfaces/qt/qtwidgets.pas
    ===================================================================
    --- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31469)
    +++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
    @@ -6196,7 +6196,7 @@
       LMScroll.Pos := p1;
       LMScroll.ScrollCode := SIF_POS;
     
    -  if not InUpdate then
    +  if not InUpdate and not getTracking then
         DeliverMessage(LMScroll);
     
       b := p1 = getMax;
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31469)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
    @@ -2664,18 +2665,17 @@
     var
       Msg: TLMVScroll;
       MaxValue: gdouble;
    -  State: PByte;
    +  Widget: PGTKWidget;
     begin
       Result := CallBackDefaultReturn;
     
    +  Widget:=PGTKWidget(ARange);
       //DebugLn(Format('Trace:[Gtk2RangeScrollCB] Value: %d', [RoundToInt(AValue)]));
       if G_OBJECT_TYPE(ARange) = gtk_hscrollbar_get_type then
         Msg.Msg := LM_HSCROLL
       else
         Msg.Msg := LM_VSCROLL;
     
    -  if (AWidgetInfo^.LCLObject is TScrollingWinControl) then
    -  begin
         if ARange^.adjustment^.page_size > 0 then
           MaxValue := ARange^.adjustment^.upper - ARange^.adjustment^.page_size
         else
    @@ -2685,7 +2685,6 @@
           Result := not Result;
           AValue := MaxValue;
         end;
    -  end;
     
       with Msg do
       begin
    @@ -2698,16 +2697,11 @@
         ScrollBar := HWND(PtrUInt(ARange));
         ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
       end;
    -  Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
    +  DeliverMessage(AWidgetInfo^.LCLObject, Msg);
     
    -  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) or
    -    not Assigned(AWidgetInfo^.UserData) then exit;
    -
    -  State:=AWidgetInfo^.UserData;
    -
       if Msg.Scrollcode=SB_THUMBTRACK then
       begin
    -    if State^ = 0 then
    +    if Widget^.state = 0 then
         begin
           Msg.ScrollCode := SB_THUMBPOSITION;
           DeliverMessage(AWidgetInfo^.LCLObject, Msg);
    @@ -2715,22 +2709,14 @@
           DeliverMessage(AWidgetInfo^.LCLObject, Msg);
         end;
       end
    -  else State^:=1;
    +  else Widget^.state := 1;
     end;
     
     function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
       Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
    -var
    -  State: PByte;
    -  WidgetInfo: PWidgetInfo;
     begin
    -  WidgetInfo:=GetWidgetInfo(Widget, false);
    -  if Assigned(WidgetInfo^.UserData) then
    -  begin
    -    State:=WidgetInfo^.UserData;
    -    State^:=2;
    -  end;
    -  Result:=False;
    +  Widget^.state := 2;
    +  Result := CallBackDefaultReturn;;
     end;
     
     function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
    @@ -2738,17 +2724,15 @@
     var
       Avalue: gdouble;
       WidgetInfo: PWidgetInfo;
    -  State: PByte;
     begin
       AValue:=PGtkRange(Widget)^.adjustment^.value;
    -  WidgetInfo:=GetWidgetInfo(Widget, false);
    -  If Assigned(WidgetInfo^.UserData) then
    -  begin
    -    State:=WidgetInfo^.UserData;
    -    if State^=1 then Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    -    State^:=0;
    -  end;
    -  Result:=False;
    +  WidgetInfo:=GetWidgetInfo(Widget, False);
    +  if not Assigned(WidgetInfo) then
    +    WidgetInfo:=GetWidgetInfo(Widget^.parent, False);
    +  if Assigned(WidgetInfo) and (Widget^.state = 1) then
    +    Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
    +  Widget^.state := 0;
    +  Result := CallBackDefaultReturn;
     end;
     
     function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
    Index: lcl/interfaces/gtk2/gtk2wscontrols.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wscontrols.pp	(revisión: 31469)
    +++ lcl/interfaces/gtk2/gtk2wscontrols.pp	(copia de trabajo)
    @@ -190,6 +190,14 @@
         TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
       g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value',
         TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
    +  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
    +  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
    +    g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-press-event',
    +    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
    +  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-release-event',
    +    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
     
       g_signal_connect(Widget, 'scroll-event', TGCallback(@Gtk2ScrolledWindowScrollCB), WidgetInfo);
     end;
    Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31469)
    +++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
    @@ -2442,7 +2442,6 @@
       Adjustment: PGtkAdjustment = nil;
       Widget: PGtkWidget;
       WidgetInfo: PWidgetInfo;
    -  State: PByte;
     begin
       with TScrollBar(AWinControl) do
       begin
    @@ -2464,11 +2463,6 @@
       {$ENDIF}
       WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams);
     
    -  WidgetInfo^.DataOwner:=True;
    -  State:=New(PByte);
    -  WidgetInfo^.UserData:=State;
    -  State^:=0;
    -
       Set_RC_Name(AWinControl, Widget);
       SetCallbacks(Widget, WidgetInfo);
     end;
    
    
    test_scroll2.diff (5,275 bytes)

Relationships

has duplicate 0017262 resolvedJuha Manninen Scrollbar SB_ENDSCROLL event never generated 
related to 0020733 acknowledged After SB_THUMBPOSITION never receive a SB_ENDSCROLL 

Activities

Fabio Luis Girardi

2009-10-06 13:44

reporter   ~0031148

The procedure that isn't signaled with this code is TScrollBar.Scroll

Zeljan Rikalo

2011-04-04 08:09

developer   ~0047159

Please attach example.

moe

2011-06-23 01:39

reporter   ~0049320

Try somenthing like this...

procedure THlavni.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
  var ScrollPos: Integer);
begin
    Label2.Caption:= IntToStr(Integer(ScrollCode)) + ' ' + IntToStr(Integer(scEndScroll));
end;


Note that ScrollCode never reaches scEndScroll value. Tested on Linux Qt and GTK2. And there is more...

scLineUp - works on both widgesets
scLineDown - works on both widgesets
scPageUp - works on both widgesets
scPageDown - works on both widgesets
scPosition - On Gtk2 this is fired when moving thumb, on Qt does nothing
scTrack - On Qt this is fired when moving thumb, on Gtk2 does nothing
scTop - never fired
scBottom - never fired
scEndScroll - never fired

Fabio Luis Girardi

2011-06-23 01:45

reporter   ~0049321

Sorry, I'll provide a example, soon as possible.

August Klein

2011-06-27 15:47

reporter   ~0049454

Last edited: 2011-06-28 14:42

I upload a patch for this issue.

It implements scEndScroll messages for GTK2 and Qt. Also it fixes inconsistencies between widgetsets and between them and Delphi.

(@moe, with Delphi, scTop and scBottom do not fire with mouse actions. So that's fine.)

Also I upload a project for testing.

Edit: New patch uploaded.

2011-06-27 15:48

 

scrollcode_test.zip (2,725 bytes)

2011-06-27 15:48

 

scrollcodes.diff (5,646 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31416)
+++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
@@ -6230,7 +6230,15 @@
   SliderAction := SliderActions[Action];
 
   case SliderAction of
-    QAbstractSliderSliderNoAction: Exit;
+    QAbstractSliderSliderNoAction:
+    begin
+      if getTracking and getSliderDown then
+      begin
+        LMScroll.ScrollCode := SB_THUMBPOSITION;
+        DeliverMessage(LMScroll);
+      end;
+    LMScroll.ScrollCode := SB_ENDSCROLL;
+    end;
     QAbstractSliderSliderSingleStepAdd:
       begin
         if LMScroll.Msg = LM_HSCROLL then
@@ -6273,15 +6281,8 @@
         else
           LMScroll.ScrollCode := SB_BOTTOM;
       end;
-    QAbstractSliderSliderMove:
-      begin
-        if getTracking and getSliderDown then
-          LMScroll.ScrollCode := SB_THUMBTRACK
-        else
-          LMScroll.ScrollCode := SB_THUMBPOSITION;
-      end;
+    QAbstractSliderSliderMove: LMScroll.ScrollCode := SB_THUMBTRACK;
   end;
-
   DeliverMessage(LMScroll);
 end;
 
@@ -6352,7 +6353,16 @@
         Result := inherited EventFilter(Sender, Event)
       else
         Result := False;
+      if QEvent_type(Event) = QEventKeyRelease  then
+      QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                        QAbstractSliderSliderNoAction);
     end;
+    QEventMouseButtonPress:
+    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                        QAbstractSliderSliderMove);
+    QEventMouseButtonRelease:
+    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                        QAbstractSliderSliderNoAction);
   else
     if FOwnWidget then
       Result := inherited EventFilter(Sender, Event);
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
@@ -2698,8 +2699,46 @@
     ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
   end;
   Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
+
+  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) then exit;
+
+  if Msg.Scrollcode=SB_THUMBTRACK then
+  begin
+    if PGTKWidget(ARange)^.state = 0 then
+    begin
+      Msg.ScrollCode := SB_THUMBPOSITION;
+      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
+      Msg.ScrollCode:=SB_ENDSCROLL;
+      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
+    end;
+    PGTKWidget(Arange)^.state:=2;
+  end
+  else PGTKWidget(Arange)^.state:=1;
 end;
 
+function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+begin
+  Widget^.state:=2;
+  Result:=False;
+end;
+
+function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+var
+  Avalue: gdouble;
+  WidgetInfo: PWidgetInfo;
+begin
+  AValue:=PGtkRange(Widget)^.adjustment^.value;
+  WidgetInfo:=GetWidgetInfo(Widget, false);
+
+  if Assigned(WidgetInfo) and (Widget^.state=1) then
+  Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
+
+  Widget^.state:=0;
+  Result:=False;
+end;
+
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
 var
   Msg: TLMVScroll;
Index: lcl/interfaces/gtk2/gtk2proc.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.pp	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2proc.pp	(copia de trabajo)
@@ -206,6 +206,10 @@
 // PGtkRange cb
 function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
   AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
+function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
   AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
 function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
Index: lcl/interfaces/gtk2/gtk2proc.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
@@ -377,7 +377,7 @@
 begin
   case ScrollType of
       GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
-      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
+      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
       GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
       GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
       GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
@@ -2430,6 +2430,11 @@
   TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
   
   g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
+  g_signal_connect(AGtkWidget, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
+  g_signal_connect(AGtkWidget, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
+
 end;
 
 class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl;
scrollcodes.diff (5,646 bytes)

2011-06-27 21:31

 

scrollcodes2.diff (5,503 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31416)
+++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
@@ -6230,7 +6230,15 @@
   SliderAction := SliderActions[Action];
 
   case SliderAction of
-    QAbstractSliderSliderNoAction: Exit;
+    QAbstractSliderSliderNoAction:
+    begin
+      if getTracking and getSliderDown then
+      begin
+        LMScroll.ScrollCode := SB_THUMBPOSITION;
+        DeliverMessage(LMScroll);
+      end;
+    LMScroll.ScrollCode := SB_ENDSCROLL;
+    end;
     QAbstractSliderSliderSingleStepAdd:
       begin
         if LMScroll.Msg = LM_HSCROLL then
@@ -6273,15 +6281,8 @@
         else
           LMScroll.ScrollCode := SB_BOTTOM;
       end;
-    QAbstractSliderSliderMove:
-      begin
-        if getTracking and getSliderDown then
-          LMScroll.ScrollCode := SB_THUMBTRACK
-        else
-          LMScroll.ScrollCode := SB_THUMBPOSITION;
-      end;
+    QAbstractSliderSliderMove: LMScroll.ScrollCode := SB_THUMBTRACK;
   end;
-
   DeliverMessage(LMScroll);
 end;
 
@@ -6352,7 +6353,13 @@
         Result := inherited EventFilter(Sender, Event)
       else
         Result := False;
+      if QEvent_type(Event) = QEventKeyRelease  then
+      QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                        QAbstractSliderSliderNoAction);
     end;
+    QEventMouseButtonRelease:
+    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                        QAbstractSliderSliderNoAction);
   else
     if FOwnWidget then
       Result := inherited EventFilter(Sender, Event);
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
@@ -2698,8 +2699,46 @@
     ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
   end;
   Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
+
+  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) then exit;
+
+  if Msg.Scrollcode=SB_THUMBTRACK then
+  begin
+    if PGTKWidget(ARange)^.state = 0 then
+    begin
+      Msg.ScrollCode := SB_THUMBPOSITION;
+      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
+      Msg.ScrollCode:=SB_ENDSCROLL;
+      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
+    end;
+    PGTKWidget(Arange)^.state:=2;
+  end
+  else PGTKWidget(Arange)^.state:=1;
 end;
 
+function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+begin
+  Widget^.state:=2;
+  Result:=False;
+end;
+
+function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+var
+  Avalue: gdouble;
+  WidgetInfo: PWidgetInfo;
+begin
+  AValue:=PGtkRange(Widget)^.adjustment^.value;
+  WidgetInfo:=GetWidgetInfo(Widget, false);
+
+  if Assigned(WidgetInfo) and (Widget^.state=1) then
+  Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
+
+  Widget^.state:=0;
+  Result:=False;
+end;
+
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
 var
   Msg: TLMVScroll;
Index: lcl/interfaces/gtk2/gtk2proc.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.pp	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2proc.pp	(copia de trabajo)
@@ -206,6 +206,10 @@
 // PGtkRange cb
 function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
   AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
+function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
   AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
 function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
Index: lcl/interfaces/gtk2/gtk2proc.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
@@ -377,7 +377,7 @@
 begin
   case ScrollType of
       GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
-      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
+      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
       GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
       GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
       GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
@@ -2430,6 +2430,11 @@
   TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
   
   g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
+  g_signal_connect(AGtkWidget, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
+  g_signal_connect(AGtkWidget, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
+
 end;
 
 class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl;
scrollcodes2.diff (5,503 bytes)

Juha Manninen

2011-06-28 10:16

developer   ~0049471

I tested scrollcodes2.diff with both GTK2 and QT. It works well. I also verified it is consistent with Windows bindings behavior.

I would like to apply this patch soon unless someone finds a problem from it.

August Klein

2011-06-28 14:41

reporter   ~0049474

Myself ;-). I uploaded a new patch with following changes:

Qt: 1) Do not fire multiple scEndScroll messages when you hold the key down.
    2) Now only the keys which can move scrollbar can fire scEndScroll messages.
    

GTK2: 1) (Optional) Set states into WidgetInfo.UserData pointer instead -less convenient- GTKTypeState. It was a workaround, although it worked the same way.

I hope it's the latest one. Regards.

2011-06-28 14:44

 

scrollcodes3.diff (6,705 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31416)
+++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
@@ -6230,7 +6230,15 @@
   SliderAction := SliderActions[Action];
 
   case SliderAction of
-    QAbstractSliderSliderNoAction: Exit;
+    QAbstractSliderSliderNoAction:
+    begin
+      if getTracking and getSliderDown then
+      begin
+        LMScroll.ScrollCode := SB_THUMBPOSITION;
+        DeliverMessage(LMScroll);
+      end;
+    LMScroll.ScrollCode := SB_ENDSCROLL;
+    end;
     QAbstractSliderSliderSingleStepAdd:
       begin
         if LMScroll.Msg = LM_HSCROLL then
@@ -6273,13 +6281,7 @@
         else
           LMScroll.ScrollCode := SB_BOTTOM;
       end;
-    QAbstractSliderSliderMove:
-      begin
-        if getTracking and getSliderDown then
-          LMScroll.ScrollCode := SB_THUMBTRACK
-        else
-          LMScroll.ScrollCode := SB_THUMBPOSITION;
-      end;
+    QAbstractSliderSliderMove: LMScroll.ScrollCode := SB_THUMBTRACK;
   end;
 
   DeliverMessage(LMScroll);
@@ -6352,7 +6354,20 @@
         Result := inherited EventFilter(Sender, Event)
       else
         Result := False;
+      if (QEvent_type(Event) = QEventKeyRelease) and not
+        (QKeyEvent_isAutoRepeat(QKeyEventH(event))) then
+        begin
+          Case QKeyEvent_key(QKeyEventH(Event)) of
+            QtKey_Left, QtKey_Up, QtKey_Right, QtKey_Down,
+            QtKey_PageUp, QtKey_PageDown, QtKey_Home, QtKey_End:
+              QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                       QAbstractSliderSliderNoAction);
+          end;
+        end;
     end;
+    QEventMouseButtonRelease:
+    QAbstractSlider_triggerAction(QAbstractSliderH(Widget),
+                        QAbstractSliderSliderNoAction);
   else
     if FOwnWidget then
       Result := inherited EventFilter(Sender, Event);
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
@@ -2664,6 +2665,7 @@
 var
   Msg: TLMVScroll;
   MaxValue: gdouble;
+  State: PByte;
 begin
   Result := CallBackDefaultReturn;
 
@@ -2698,8 +2700,58 @@
     ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
   end;
   Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
+
+  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) or
+    not Assigned(AWidgetInfo^.UserData) then exit;
+
+  State:=AWidgetInfo^.UserData;
+
+  if Msg.Scrollcode=SB_THUMBTRACK then
+  begin
+    if State^ = 0 then
+    begin
+      Msg.ScrollCode := SB_THUMBPOSITION;
+      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
+      Msg.ScrollCode:=SB_ENDSCROLL;
+      DeliverMessage(AWidgetInfo^.LCLObject, Msg);
+    end;
+  end
+  else State^:=1;
 end;
 
+function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+var
+  State: PByte;
+  WidgetInfo: PWidgetInfo;
+begin
+  WidgetInfo:=GetWidgetInfo(Widget, false);
+  if Assigned(WidgetInfo^.UserData) then
+  begin
+    State:=WidgetInfo^.UserData;
+    State^:=2;
+  end;
+  Result:=False;
+end;
+
+function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+var
+  Avalue: gdouble;
+  WidgetInfo: PWidgetInfo;
+  State: PByte;
+begin
+  AValue:=PGtkRange(Widget)^.adjustment^.value;
+  WidgetInfo:=GetWidgetInfo(Widget, false);
+  If Assigned(WidgetInfo^.UserData) then
+  begin
+    State:=WidgetInfo^.UserData;
+    if State^=1 then Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
+    State^:=0;
+  end;
+  Result:=False;
+end;
+
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
 var
   Msg: TLMVScroll;
Index: lcl/interfaces/gtk2/gtk2proc.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.pp	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2proc.pp	(copia de trabajo)
@@ -206,6 +206,10 @@
 // PGtkRange cb
 function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
   AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
+function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
+function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
+  Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
   AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
 function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
Index: lcl/interfaces/gtk2/gtk2proc.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
@@ -377,7 +377,7 @@
 begin
   case ScrollType of
       GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
-      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
+      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
       GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
       GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
       GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31416)
+++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
@@ -2430,6 +2430,10 @@
   TGtk2WSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject));
   
   g_signal_connect(AGtkWidget, 'change-value', TGCallback(@Gtk2RangeScrollCB), AWidgetInfo);
+  g_signal_connect(AGtkWidget, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), AWidgetInfo);
+  g_signal_connect(AGtkWidget, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), AWidgetInfo);
 end;
 
 class function TGtk2WSScrollBar.CreateHandle(const AWinControl: TWinControl;
@@ -2438,6 +2442,7 @@
   Adjustment: PGtkAdjustment = nil;
   Widget: PGtkWidget;
   WidgetInfo: PWidgetInfo;
+  State: PByte;
 begin
   with TScrollBar(AWinControl) do
   begin
@@ -2458,6 +2463,12 @@
   DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl));
   {$ENDIF}
   WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams);
+
+  WidgetInfo^.DataOwner:=True;
+  State:=New(PByte);
+  WidgetInfo^.UserData:=State;
+  State^:=0;
+
   Set_RC_Name(AWinControl, Widget);
   SetCallbacks(Widget, WidgetInfo);
 end;
scrollcodes3.diff (6,705 bytes)

moe

2011-06-28 15:58

reporter   ~0049477

@August Klein, thaks for explanation, I didn't know. However I'm still concerned about scPosition and scTrack behaving differently on Qt and Gtk2. It's not like I need them for something. I have only noticed it when testing scEndScroll.

Thank's for patch, Will it be commited to svn someday?

Regards.

Juha Manninen

2011-06-28 17:21

developer   ~0049481

@moe:
> However I'm still concerned about scPosition and scTrack behaving differently on Qt and Gtk2.

Which way differently?

> Thank's for patch, Will it be commited to svn someday?

If you test it and verify it works, then I promise to commit it. :)

moe

2011-06-28 22:25

reporter   ~0049487

Confirming, patch work flawelessly. At least for me.

@Juha Manninen, on Gtk2 scPosition was fired instead of scTrack, but never mind, it seems that now all works as expected.

Regrds

Fabio Luis Girardi

2011-06-29 01:18

reporter   ~0049488

The last patch works perfectly!

Juha Manninen

2011-06-29 02:17

developer   ~0049489

Please test and close if OK.

Fabio Luis Girardi

2011-06-29 03:29

reporter   ~0049491

Working fine!

Jesus Reyes

2011-06-29 20:39

developer   ~0049509

Last edited: 2011-06-29 20:47

It may have fixed TScrollbar but it broke all TCustomControls that handle scrollbars, like the grid.

See the attached example, while dragging the ThumbBar it only register scrollcode 5 (SB_THUMBTRACK) and SB_ENDSCROLL is never triggered nor SB_THUMBPOSITION. (only tested GTK2)

once this example is fixed I will fix the grids.

August Klein

2011-06-29 22:11

reporter   ~0049514

Try reverting this and comfirm me if it works:

http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/lcl/interfaces/gtk2/gtk2proc.inc?root=lazarus&r1=31447&r2=31446&pathrev=31447

Later I'll look more deeply.

August Klein

2011-06-30 01:39

reporter   ~0049520

Fix uploaded.
 
Now only TScrollBar trigger SB_THUMBTRACK. Others trigger SB_THUMBPOSITION as before. Note that SB_ENDSCROLL was not fired before patches.

2011-06-30 01:40

 

scrolltype.diff (1,559 bytes)
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31457)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
@@ -2696,6 +2697,11 @@
       SmallPos := High(SmallPos);
 
     ScrollBar := HWND(PtrUInt(ARange));
+
+    if (AWidgetInfo^.LCLObject is TScrollBar) and
+      (ASCrollType = GTK_SCROLL_JUMP) then
+       AScrollType := -1;
+
     ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
   end;
   Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
Index: lcl/interfaces/gtk2/gtk2proc.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.inc	(revisión: 31457)
+++ lcl/interfaces/gtk2/gtk2proc.inc	(copia de trabajo)
@@ -377,7 +377,7 @@
 begin
   case ScrollType of
       GTK_SCROLL_NONE          : Result := SB_ENDSCROLL;
-      GTK_SCROLL_JUMP          : Result := SB_THUMBTRACK;
+      GTK_SCROLL_JUMP          : Result := SB_THUMBPOSITION;
       GTK_SCROLL_STEP_BACKWARD : Result := SB_LINELEFT;
       GTK_SCROLL_STEP_FORWARD  : Result := SB_LINERIGHT;
       GTK_SCROLL_PAGE_BACKWARD : Result := SB_PAGELEFT;
@@ -391,7 +391,8 @@
       GTK_SCROLL_PAGE_LEFT     : Result := SB_PAGELEFT;
       GTK_SCROLL_PAGE_RIGHT    : Result := SB_PAGERIGHT;
       GTK_SCROLL_START         : Result := SB_TOP;
-      GTK_SCROLL_END           : Result := SB_BOTTOM;
+      GTK_SCROLL_END           : Result := SB_BOTTOM
+      else Result:=SB_THUMBTRACK;
     end;
 end;
 

scrolltype.diff (1,559 bytes)

Jesus Reyes

2011-06-30 02:18

developer   ~0049522

I have not checked the patch, but, if now SB_ENDSCROLL can be detected it would be the best to unify scrollbar handling everywhere. This way if SB_THUMBPOSITION is sent just before SB_ENDSCROLL, I would better use SB_THUMBTRACK for the grid instead of SB_THUMBPOSITION. Do you think it could be made?

August Klein

2011-06-30 10:57

reporter   ~0049529

I think so.

Try 'test_scroll' patch and give me your feedback.
With it, GTK2 and Qt should send the same scroll messages than Windows.

2011-06-30 10:58

 

test_scroll.diff (4,762 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31469)
+++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
@@ -6196,7 +6196,7 @@
   LMScroll.Pos := p1;
   LMScroll.ScrollCode := SIF_POS;
 
-  if not InUpdate then
+  if not InUpdate and not getTracking then
     DeliverMessage(LMScroll);
 
   b := p1 = getMax;
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31469)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
@@ -2664,10 +2665,11 @@
 var
   Msg: TLMVScroll;
   MaxValue: gdouble;
-  State: PByte;
+  Widget: PGTKWidget;
 begin
   Result := CallBackDefaultReturn;
 
+  Widget:=PGTKWidget(ARange);
   //DebugLn(Format('Trace:[Gtk2RangeScrollCB] Value: %d', [RoundToInt(AValue)]));
   if G_OBJECT_TYPE(ARange) = gtk_hscrollbar_get_type then
     Msg.Msg := LM_HSCROLL
@@ -2700,14 +2702,9 @@
   end;
   Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
 
-  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) or
-    not Assigned(AWidgetInfo^.UserData) then exit;
-
-  State:=AWidgetInfo^.UserData;
-
   if Msg.Scrollcode=SB_THUMBTRACK then
   begin
-    if State^ = 0 then
+    if Widget^.state = 0 then
     begin
       Msg.ScrollCode := SB_THUMBPOSITION;
       DeliverMessage(AWidgetInfo^.LCLObject, Msg);
@@ -2715,22 +2712,14 @@
       DeliverMessage(AWidgetInfo^.LCLObject, Msg);
     end;
   end
-  else State^:=1;
+  else Widget^.state := 1;
 end;
 
 function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
   Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
-var
-  State: PByte;
-  WidgetInfo: PWidgetInfo;
 begin
-  WidgetInfo:=GetWidgetInfo(Widget, false);
-  if Assigned(WidgetInfo^.UserData) then
-  begin
-    State:=WidgetInfo^.UserData;
-    State^:=2;
-  end;
-  Result:=False;
+  Widget^.state := 2;
+  Result := CallBackDefaultReturn;;
 end;
 
 function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
@@ -2738,17 +2727,15 @@
 var
   Avalue: gdouble;
   WidgetInfo: PWidgetInfo;
-  State: PByte;
 begin
   AValue:=PGtkRange(Widget)^.adjustment^.value;
-  WidgetInfo:=GetWidgetInfo(Widget, false);
-  If Assigned(WidgetInfo^.UserData) then
-  begin
-    State:=WidgetInfo^.UserData;
-    if State^=1 then Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
-    State^:=0;
-  end;
-  Result:=False;
+  WidgetInfo:=GetWidgetInfo(Widget, False);
+  if not Assigned(WidgetInfo) then
+    WidgetInfo:=GetWidgetInfo(Widget^.parent, False);
+  if Assigned(WidgetInfo) and (Widget^.state = 1) then
+    Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
+  Widget^.state := 0;
+  Result := CallBackDefaultReturn;
 end;
 
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
Index: lcl/interfaces/gtk2/gtk2wscontrols.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wscontrols.pp	(revisión: 31469)
+++ lcl/interfaces/gtk2/gtk2wscontrols.pp	(copia de trabajo)
@@ -190,6 +190,14 @@
     TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
   g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value',
     TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
+  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
+  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
+    g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
+  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
 
   g_signal_connect(Widget, 'scroll-event', TGCallback(@Gtk2ScrolledWindowScrollCB), WidgetInfo);
 end;
Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31469)
+++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
@@ -2442,7 +2442,6 @@
   Adjustment: PGtkAdjustment = nil;
   Widget: PGtkWidget;
   WidgetInfo: PWidgetInfo;
-  State: PByte;
 begin
   with TScrollBar(AWinControl) do
   begin
@@ -2464,11 +2463,6 @@
   {$ENDIF}
   WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams);
 
-  WidgetInfo^.DataOwner:=True;
-  State:=New(PByte);
-  WidgetInfo^.UserData:=State;
-  State^:=0;
-
   Set_RC_Name(AWinControl, Widget);
   SetCallbacks(Widget, WidgetInfo);
 end;
test_scroll.diff (4,762 bytes)

Jesus Reyes

2011-06-30 23:16

developer   ~0049547

Event notification works seems to work fine here, only tested gtk2, can somebody test under Mac?

There are still some problems/differences on reported values in gtk and windows, but that is not related to this patch, I will update scrollbar testing project so everybody can try in his OS/widgetset combination.

However I don't want to apply it yet but wait until reporting values differences in windows/gtk are investigated and solved (if somebody want to take a look at this, write here, I will be investigating this also) then a series of quick patches should resolve all scrollbar problems.

2011-06-30 23:17

 

scrollbartester.tar.gz (3,579 bytes)

August Klein

2011-07-01 01:29

reporter   ~0049548

New patch for test. It solves some problems described on Gtk2.

2011-07-01 01:29

 

test_scroll2.diff (5,275 bytes)
Index: lcl/interfaces/qt/qtwidgets.pas
===================================================================
--- lcl/interfaces/qt/qtwidgets.pas	(revisión: 31469)
+++ lcl/interfaces/qt/qtwidgets.pas	(copia de trabajo)
@@ -6196,7 +6196,7 @@
   LMScroll.Pos := p1;
   LMScroll.ScrollCode := SIF_POS;
 
-  if not InUpdate then
+  if not InUpdate and not getTracking then
     DeliverMessage(LMScroll);
 
   b := p1 = getMax;
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revisión: 31469)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(copia de trabajo)
@@ -2664,18 +2665,17 @@
 var
   Msg: TLMVScroll;
   MaxValue: gdouble;
-  State: PByte;
+  Widget: PGTKWidget;
 begin
   Result := CallBackDefaultReturn;
 
+  Widget:=PGTKWidget(ARange);
   //DebugLn(Format('Trace:[Gtk2RangeScrollCB] Value: %d', [RoundToInt(AValue)]));
   if G_OBJECT_TYPE(ARange) = gtk_hscrollbar_get_type then
     Msg.Msg := LM_HSCROLL
   else
     Msg.Msg := LM_VSCROLL;
 
-  if (AWidgetInfo^.LCLObject is TScrollingWinControl) then
-  begin
     if ARange^.adjustment^.page_size > 0 then
       MaxValue := ARange^.adjustment^.upper - ARange^.adjustment^.page_size
     else
@@ -2685,7 +2685,6 @@
       Result := not Result;
       AValue := MaxValue;
     end;
-  end;
 
   with Msg do
   begin
@@ -2698,16 +2697,11 @@
     ScrollBar := HWND(PtrUInt(ARange));
     ScrollCode := GtkScrollTypeToScrollCode(AScrollType);
   end;
-  Result := DeliverMessage(AWidgetInfo^.LCLObject, Msg) <> 0;
+  DeliverMessage(AWidgetInfo^.LCLObject, Msg);
 
-  if not Result or not (AWidgetInfo^.LCLObject is TScrollBar) or
-    not Assigned(AWidgetInfo^.UserData) then exit;
-
-  State:=AWidgetInfo^.UserData;
-
   if Msg.Scrollcode=SB_THUMBTRACK then
   begin
-    if State^ = 0 then
+    if Widget^.state = 0 then
     begin
       Msg.ScrollCode := SB_THUMBPOSITION;
       DeliverMessage(AWidgetInfo^.LCLObject, Msg);
@@ -2715,22 +2709,14 @@
       DeliverMessage(AWidgetInfo^.LCLObject, Msg);
     end;
   end
-  else State^:=1;
+  else Widget^.state := 1;
 end;
 
 function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
   Event: PGdkEventButton; Data: gPointer): gboolean; cdecl;
-var
-  State: PByte;
-  WidgetInfo: PWidgetInfo;
 begin
-  WidgetInfo:=GetWidgetInfo(Widget, false);
-  if Assigned(WidgetInfo^.UserData) then
-  begin
-    State:=WidgetInfo^.UserData;
-    State^:=2;
-  end;
-  Result:=False;
+  Widget^.state := 2;
+  Result := CallBackDefaultReturn;;
 end;
 
 function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
@@ -2738,17 +2724,15 @@
 var
   Avalue: gdouble;
   WidgetInfo: PWidgetInfo;
-  State: PByte;
 begin
   AValue:=PGtkRange(Widget)^.adjustment^.value;
-  WidgetInfo:=GetWidgetInfo(Widget, false);
-  If Assigned(WidgetInfo^.UserData) then
-  begin
-    State:=WidgetInfo^.UserData;
-    if State^=1 then Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
-    State^:=0;
-  end;
-  Result:=False;
+  WidgetInfo:=GetWidgetInfo(Widget, False);
+  if not Assigned(WidgetInfo) then
+    WidgetInfo:=GetWidgetInfo(Widget^.parent, False);
+  if Assigned(WidgetInfo) and (Widget^.state = 1) then
+    Gtk2RangeScrollCB(PGtkRange(Widget), 0, AValue, WidgetInfo);
+  Widget^.state := 0;
+  Result := CallBackDefaultReturn;
 end;
 
 function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
Index: lcl/interfaces/gtk2/gtk2wscontrols.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wscontrols.pp	(revisión: 31469)
+++ lcl/interfaces/gtk2/gtk2wscontrols.pp	(copia de trabajo)
@@ -190,6 +190,14 @@
     TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
   g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'change-value',
     TGCallback(@Gtk2RangeScrollCB), WidgetInfo);
+  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
+  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.hscrollbar, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
+    g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-press-event',
+    TGCallback(@Gtk2RangeScrollPressCB), WidgetInfo);
+  g_signal_connect(GTK_SCROLLED_WINDOW(Widget)^.vscrollbar, 'button-release-event',
+    TGCallback(@Gtk2RangeScrollReleaseCB), WidgetInfo);
 
   g_signal_connect(Widget, 'scroll-event', TGCallback(@Gtk2ScrolledWindowScrollCB), WidgetInfo);
 end;
Index: lcl/interfaces/gtk2/gtk2wsstdctrls.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(revisión: 31469)
+++ lcl/interfaces/gtk2/gtk2wsstdctrls.pp	(copia de trabajo)
@@ -2442,7 +2442,6 @@
   Adjustment: PGtkAdjustment = nil;
   Widget: PGtkWidget;
   WidgetInfo: PWidgetInfo;
-  State: PByte;
 begin
   with TScrollBar(AWinControl) do
   begin
@@ -2464,11 +2463,6 @@
   {$ENDIF}
   WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams);
 
-  WidgetInfo^.DataOwner:=True;
-  State:=New(PByte);
-  WidgetInfo^.UserData:=State;
-  State^:=0;
-
   Set_RC_Name(AWinControl, Widget);
   SetCallbacks(Widget, WidgetInfo);
 end;

test_scroll2.diff (5,275 bytes)

Jesus Reyes

2011-07-01 05:36

developer   ~0049550

Works fine here. There are some differences on the reported values under gtk2, but is the matter of another report. Thanks.

Zeljan Rikalo

2011-07-01 09:21

developer   ~0049553

I'm not sure that qt part of patch is correct. If there's tracking enabled on scrollbar message will never be delivered, also qt-4.6.X should be tested with this patch.

Issue History

Date Modified Username Field Change
2009-10-06 01:28 Fabio Luis Girardi New Issue
2009-10-06 01:28 Fabio Luis Girardi Widgetset => GTK 2, QT
2009-10-06 13:44 Fabio Luis Girardi Note Added: 0031148
2009-10-20 22:10 Vincent Snijders LazTarget => 1.0
2009-10-20 22:10 Vincent Snijders Status new => acknowledged
2009-10-20 22:10 Vincent Snijders Target Version => 1.0.0
2011-04-04 08:09 Zeljan Rikalo Note Added: 0047159
2011-04-04 08:09 Zeljan Rikalo Status acknowledged => feedback
2011-06-23 01:39 moe Note Added: 0049320
2011-06-23 01:45 Fabio Luis Girardi Note Added: 0049321
2011-06-27 15:47 August Klein Note Added: 0049454
2011-06-27 15:48 August Klein File Added: scrollcode_test.zip
2011-06-27 15:48 August Klein File Added: scrollcodes.diff
2011-06-27 21:30 August Klein Note Edited: 0049454
2011-06-27 21:31 August Klein File Added: scrollcodes2.diff
2011-06-28 10:16 Juha Manninen Note Added: 0049471
2011-06-28 14:41 August Klein Note Added: 0049474
2011-06-28 14:42 August Klein Note Edited: 0049454
2011-06-28 14:44 August Klein File Added: scrollcodes3.diff
2011-06-28 15:58 moe Note Added: 0049477
2011-06-28 17:21 Juha Manninen Note Added: 0049481
2011-06-28 22:25 moe Note Added: 0049487
2011-06-29 01:18 Fabio Luis Girardi Note Added: 0049488
2011-06-29 02:17 Juha Manninen Fixed in Revision => r31447
2011-06-29 02:17 Juha Manninen Status feedback => resolved
2011-06-29 02:17 Juha Manninen Resolution open => fixed
2011-06-29 02:17 Juha Manninen Assigned To => Juha Manninen
2011-06-29 02:17 Juha Manninen Note Added: 0049489
2011-06-29 03:29 Fabio Luis Girardi Status resolved => closed
2011-06-29 03:29 Fabio Luis Girardi Note Added: 0049491
2011-06-29 20:39 Jesus Reyes LazTarget 1.0 => 0.99.0
2011-06-29 20:39 Jesus Reyes Status closed => assigned
2011-06-29 20:39 Jesus Reyes Resolution fixed => reopened
2011-06-29 20:39 Jesus Reyes Note Added: 0049509
2011-06-29 20:39 Jesus Reyes Target Version 1.0.0 => 0.99.0
2011-06-29 20:40 Jesus Reyes File Added: published.tar.gz
2011-06-29 20:47 Jesus Reyes Note Edited: 0049509
2011-06-29 22:11 August Klein Note Added: 0049514
2011-06-30 01:39 August Klein Note Added: 0049520
2011-06-30 01:40 August Klein File Added: scrolltype.diff
2011-06-30 02:18 Jesus Reyes Note Added: 0049522
2011-06-30 10:57 August Klein Note Added: 0049529
2011-06-30 10:58 August Klein File Added: test_scroll.diff
2011-06-30 23:16 Jesus Reyes Note Added: 0049547
2011-06-30 23:17 Jesus Reyes File Added: scrollbartester.tar.gz
2011-06-30 23:17 Jesus Reyes File Deleted: published.tar.gz
2011-07-01 01:29 August Klein Note Added: 0049548
2011-07-01 01:29 August Klein File Added: test_scroll2.diff
2011-07-01 05:36 Jesus Reyes Fixed in Revision r31447 => r31447, 31483
2011-07-01 05:36 Jesus Reyes Status assigned => resolved
2011-07-01 05:36 Jesus Reyes Fixed in Version => 0.9.31 (SVN)
2011-07-01 05:36 Jesus Reyes Resolution reopened => fixed
2011-07-01 05:36 Jesus Reyes Note Added: 0049550
2011-07-01 09:21 Zeljan Rikalo Note Added: 0049553
2011-11-19 00:41 Juha Manninen Relationship added has duplicate 0017262
2011-11-22 20:19 Juha Manninen Relationship added related to 0020733
2014-07-11 13:53 Fabio Luis Girardi Status resolved => closed