-static void gtk_spinbutt_callback( GtkWidget *WXUNUSED(widget), wxSpinButton *win )
-{
- if (!win->HasVMT()) return;
- if (g_blockEventsOnDrag) return;
-
- float diff = win->m_adjust->value - win->m_oldPos;
- if (fabs(diff) < 0.2) return;
- win->m_oldPos = win->m_adjust->value;
-
- wxEventType command = wxEVT_NULL;
-
- float line_step = win->m_adjust->step_increment;
- float page_step = win->m_adjust->page_increment;
-
- if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
- else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
- else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
- else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
- else command = wxEVT_SCROLL_THUMBTRACK;
-
- int value = (int)(win->m_adjust->value+0.5);
-
- wxSpinEvent event( command, win->GetId());
- event.SetPosition( value );
- event.SetOrientation( wxVERTICAL );
- event.SetEventObject( win );
-
- win->GetEventHandler()->ProcessEvent( event );
+extern "C" {
+static void
+gtk_value_changed(GtkSpinButton* spinbutton, wxSpinButton* win)
+{
+ if (g_isIdle) wxapp_install_idle_handler();
+
+ const double value = gtk_spin_button_get_value(spinbutton);
+ const int pos = int(value);
+ const int oldPos = win->m_pos;
+ if (!win->m_hasVMT || g_blockEventsOnDrag || win->m_blockScrollEvent || pos == oldPos)
+ {
+ win->m_pos = pos;
+ return;
+ }
+
+ wxSpinEvent event(pos > oldPos ? wxEVT_SCROLL_LINEUP : wxEVT_SCROLL_LINEDOWN, win->GetId());
+ event.SetPosition(pos);
+ event.SetEventObject(win);
+
+ if ((win->GetEventHandler()->ProcessEvent( event )) &&
+ !event.IsAllowed() )
+ {
+ /* program has vetoed */
+ win->BlockScrollEvent();
+ gtk_spin_button_set_value(spinbutton, oldPos);
+ win->UnblockScrollEvent();
+ return;
+ }
+
+ win->m_pos = pos;
+
+ /* always send a thumbtrack event */
+ wxSpinEvent event2(wxEVT_SCROLL_THUMBTRACK, win->GetId());
+ event2.SetPosition(pos);
+ event2.SetEventObject(win);
+ win->GetEventHandler()->ProcessEvent(event2);
+}