Improved gpm wheel mouse support

This commit is contained in:
Markus Gans 2018-12-01 21:28:25 +01:00
parent aed6893eb4
commit 635d7c691e
11 changed files with 184 additions and 149 deletions

View File

@ -1,3 +1,7 @@
2018-12-01 Markus Gans <guru.mail@muenster.de>
* Improved wheel mouse support
* Fix compile in optimization level 2 for newer gcc
2018-11-27 Markus Gans <guru.mail@muenster.de>
* Correct vertical scrollbar position after sorting in FListView

View File

@ -120,12 +120,6 @@ Which mouse types are supported?
* General Purpose Mouse (gpm) on a linux console
How can I use the mouse wheel with GPM?
---------------------------------------
This requires a workaround. Press (and hold) the left mouse button
and then use the scroll wheel.
What do I need to compile the unit tests?
-----------------------------------------

View File

@ -501,15 +501,15 @@ inline void FApplication::findKeyboardWidget()
// Find the widget that has the keyboard focus
FWidget* widget = 0;
FWidget* focus_widget = getFocusWidget();
FWidget* move_size_widget = getMoveSizeWidget();
FWidget* focus = getFocusWidget();
FWidget* move_size = getMoveSizeWidget();
if ( focus_widget )
if ( focus )
{
if ( move_size_widget )
widget = move_size_widget;
if ( move_size )
widget = move_size;
else
widget = focus_widget;
widget = focus;
}
else
{
@ -692,11 +692,11 @@ bool FApplication::processDialogSwitchAccelerator()
if ( s > 0 && s >= n )
{
// unset the move/size mode
FWidget* move_size_widget = getMoveSizeWidget();
FWidget* move_size = getMoveSizeWidget();
if ( move_size_widget )
if ( move_size )
{
FWidget* w = move_size_widget;
FWidget* w = move_size;
setMoveSizeWidget(0);
w->redraw();
}
@ -731,11 +731,11 @@ bool FApplication::processAccelerator (const FWidget*& widget)
if ( iter->key == keyboard->getKey() )
{
// unset the move/size mode
FWidget* move_size_widget = getMoveSizeWidget();
FWidget* move_size = getMoveSizeWidget();
if ( move_size_widget )
if ( move_size )
{
FWidget* w = move_size_widget;
FWidget* w = move_size;
setMoveSizeWidget(0);
w->redraw();
}
@ -772,13 +772,13 @@ bool FApplication::getMouseEvent()
//----------------------------------------------------------------------
FWidget*& FApplication::determineClickedWidget()
{
FWidget*& clicked_widget = getClickedWidget();
FWidget*& clicked = getClickedWidget();
if ( clicked_widget )
return clicked_widget;
if ( clicked )
return clicked;
if ( ! mouse )
return clicked_widget;
return clicked;
if ( ! mouse->isLeftButtonPressed()
&& ! mouse->isLeftButtonDoubleClick()
@ -786,7 +786,7 @@ FWidget*& FApplication::determineClickedWidget()
&& ! mouse->isMiddleButtonPressed()
&& ! mouse->isWheelUp()
&& ! mouse->isWheelDown() )
return clicked_widget;
return clicked;
const FPoint& mouse_position = mouse->getPos();
@ -797,11 +797,11 @@ FWidget*& FApplication::determineClickedWidget()
{
// Determine the widget at the current click position
FWidget* child = childWidgetAt (window, mouse_position);
clicked_widget = ( child != 0 ) ? child : window;
setClickedWidget (clicked_widget);
clicked = ( child != 0 ) ? child : window;
setClickedWidget (clicked);
}
return clicked_widget;
return clicked;
}
//----------------------------------------------------------------------
@ -809,11 +809,11 @@ void FApplication::unsetMoveSizeMode()
{
// Unset the move/size mode
FWidget* move_size_widget = getMoveSizeWidget();
FWidget* move_size = getMoveSizeWidget();
if ( move_size_widget )
if ( move_size )
{
FWidget* w = move_size_widget;
FWidget* w = move_size;
setMoveSizeWidget(0);
w->redraw();
}
@ -824,10 +824,10 @@ void FApplication::closeOpenMenu()
{
// Close the open menu
FWidget* open_menu = getOpenMenu();
FMenu* menu = static_cast<FMenu*>(open_menu);
FWidget* openmenu = getOpenMenu();
FMenu* menu = static_cast<FMenu*>(openmenu);
if ( ! open_menu || ( mouse && mouse->isMoved()) )
if ( ! openmenu || ( mouse && mouse->isMoved()) )
return;
if ( mouse )
@ -867,10 +867,10 @@ void FApplication::unselectMenubarItems()
{
// Unselect the menu bar items
FWidget* open_menu = getOpenMenu();
FWidget* openmenu = getOpenMenu();
FMenuBar* menu_bar = getMenuBar();
if ( open_menu || (mouse && mouse->isMoved()) )
if ( openmenu || (mouse && mouse->isMoved()) )
return;
if ( ! menu_bar )
@ -907,9 +907,9 @@ void FApplication::unselectMenubarItems()
//----------------------------------------------------------------------
void FApplication::sendMouseEvent()
{
FWidget* clicked_widget = getClickedWidget();
FWidget* clicked = getClickedWidget();
if ( ! clicked_widget )
if ( ! clicked )
return;
if ( ! mouse )
@ -928,7 +928,7 @@ void FApplication::sendMouseEvent()
if ( mouse->isMetaKeyPressed() )
key_state |= fc::MetaButton;
widgetMousePos = clicked_widget->termToWidgetPos(mouse_position);
widgetMousePos = clicked->termToWidgetPos(mouse_position);
if ( mouse->isMoved() )
{
@ -953,7 +953,7 @@ void FApplication::sendMouseMoveEvent ( const FPoint& widgetMousePos
if ( ! mouse )
return;
FWidget* clicked_widget = getClickedWidget();
FWidget* clicked = getClickedWidget();
if ( mouse->isLeftButtonPressed() )
{
@ -961,7 +961,7 @@ void FApplication::sendMouseMoveEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::LeftButton | key_state );
sendEvent (clicked_widget, &m_down_ev);
sendEvent (clicked, &m_down_ev);
}
if ( mouse->isRightButtonPressed() )
@ -970,7 +970,7 @@ void FApplication::sendMouseMoveEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::RightButton | key_state );
sendEvent (clicked_widget, &m_down_ev);
sendEvent (clicked, &m_down_ev);
}
if ( mouse->isMiddleButtonPressed() )
@ -979,7 +979,7 @@ void FApplication::sendMouseMoveEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::MiddleButton | key_state );
sendEvent (clicked_widget, &m_down_ev);
sendEvent (clicked, &m_down_ev);
}
}
@ -991,7 +991,7 @@ void FApplication::sendMouseLeftClickEvent ( const FPoint& widgetMousePos
if ( ! mouse )
return;
FWidget* clicked_widget = getClickedWidget();
FWidget* clicked = getClickedWidget();
if ( mouse->isLeftButtonDoubleClick() )
{
@ -999,7 +999,7 @@ void FApplication::sendMouseLeftClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::LeftButton | key_state );
sendEvent (clicked_widget, &m_dblclick_ev);
sendEvent (clicked, &m_dblclick_ev);
}
else if ( mouse->isLeftButtonPressed() )
{
@ -1007,7 +1007,7 @@ void FApplication::sendMouseLeftClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::LeftButton | key_state );
sendEvent (clicked_widget, &m_down_ev);
sendEvent (clicked, &m_down_ev);
}
else if ( mouse->isLeftButtonReleased() )
{
@ -1015,7 +1015,7 @@ void FApplication::sendMouseLeftClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::LeftButton | key_state );
FWidget* released_widget = clicked_widget;
FWidget* released_widget = clicked;
if ( ! mouse->isRightButtonPressed()
&& ! mouse->isMiddleButtonPressed() )
@ -1033,7 +1033,7 @@ void FApplication::sendMouseRightClickEvent ( const FPoint& widgetMousePos
if ( ! mouse )
return;
FWidget* clicked_widget = getClickedWidget();
FWidget* clicked = getClickedWidget();
if ( mouse->isRightButtonPressed() )
{
@ -1041,7 +1041,7 @@ void FApplication::sendMouseRightClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::RightButton | key_state );
sendEvent (clicked_widget, &m_down_ev);
sendEvent (clicked, &m_down_ev);
}
else if ( mouse->isRightButtonReleased() )
{
@ -1049,7 +1049,7 @@ void FApplication::sendMouseRightClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::RightButton | key_state );
FWidget* released_widget = clicked_widget;
FWidget* released_widget = clicked;
if ( ! mouse->isLeftButtonPressed()
&& ! mouse->isMiddleButtonPressed() )
@ -1067,7 +1067,7 @@ void FApplication::sendMouseMiddleClickEvent ( const FPoint& widgetMousePos
if ( ! mouse )
return;
FWidget* clicked_widget = getClickedWidget();
FWidget* clicked = getClickedWidget();
if ( mouse->isMiddleButtonPressed() )
{
@ -1075,7 +1075,7 @@ void FApplication::sendMouseMiddleClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::MiddleButton | key_state );
sendEvent (clicked_widget, &m_down_ev);
sendEvent (clicked, &m_down_ev);
// gnome-terminal sends no released on middle click
if ( isGnomeTerminal() )
@ -1087,7 +1087,7 @@ void FApplication::sendMouseMiddleClickEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::MiddleButton | key_state );
FWidget* released_widget = clicked_widget;
FWidget* released_widget = clicked;
if ( ! mouse->isLeftButtonPressed()
&& ! mouse->isRightButtonPressed() )
@ -1106,7 +1106,7 @@ void FApplication::sendWheelEvent ( const FPoint& widgetMousePos
if ( ! mouse )
return;
FWidget* clicked_widget = getClickedWidget();
FWidget* clicked = getClickedWidget();
if ( mouse->isWheelUp() )
{
@ -1114,7 +1114,7 @@ void FApplication::sendWheelEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::WheelUp );
FWidget* scroll_over_widget = clicked_widget;
FWidget* scroll_over_widget = clicked;
setClickedWidget(0);
sendEvent(scroll_over_widget, &wheel_ev);
}
@ -1125,7 +1125,7 @@ void FApplication::sendWheelEvent ( const FPoint& widgetMousePos
, widgetMousePos
, mouse_position
, fc::WheelDown );
FWidget* scroll_over_widget = clicked_widget;
FWidget* scroll_over_widget = clicked;
setClickedWidget(0);
sendEvent (scroll_over_widget, &wheel_ev);
}

View File

@ -380,13 +380,13 @@ void FDialog::setSize (std::size_t w, std::size_t h, bool adjust)
}
// set the cursor to the focus widget
FWidget* focus_widget = FWidget::getFocusWidget();
if ( focus_widget
&& focus_widget->isVisible()
&& focus_widget->hasVisibleCursor() )
FWidget* focus = FWidget::getFocusWidget();
if ( focus
&& focus->isVisible()
&& focus->hasVisibleCursor() )
{
FPoint cursor_pos = focus_widget->getCursorPos();
focus_widget->setCursorPos(cursor_pos);
FPoint cursor_pos = focus->getCursorPos();
focus->setCursorPos(cursor_pos);
}
}
@ -1254,14 +1254,14 @@ void FDialog::setCursorToFocusWidget()
{
// Set the cursor to the focus widget
FWidget* focus_widget = FWidget::getFocusWidget();
FWidget* focus = FWidget::getFocusWidget();
if ( focus_widget
&& focus_widget->isVisible()
&& focus_widget->hasVisibleCursor() )
if ( focus
&& focus->isVisible()
&& focus->hasVisibleCursor() )
{
FPoint cursor_pos = focus_widget->getCursorPos();
focus_widget->setCursorPos(cursor_pos);
FPoint cursor_pos = focus->getCursorPos();
focus->setCursorPos(cursor_pos);
updateVTermCursor(vwin);
}
}

View File

@ -115,10 +115,10 @@ void FMenu::hide()
if ( ! isSubMenu() )
{
FMenu* open_menu = static_cast<FMenu*>(getOpenMenu());
FMenu* openmenu = static_cast<FMenu*>(getOpenMenu());
if ( open_menu && open_menu != this )
open_menu->hide();
if ( openmenu && openmenu != this )
openmenu->hide();
setOpenMenu(0);
}

View File

@ -288,23 +288,20 @@ void FMenuItem::delAccelerator (FWidget* obj)
//----------------------------------------------------------------------
void FMenuItem::openMenu()
{
FMenu* dd_menu; // Drop-down menu
FMenu* open_menu;
if ( ! hasMenu() )
return;
dd_menu = getMenu(); // Drop-down menu
FMenu* dd_menu = getMenu(); // Drop-down menu
if ( dd_menu->isVisible() )
return;
open_menu = static_cast<FMenu*>(getOpenMenu());
FMenu* openmenu = static_cast<FMenu*>(getOpenMenu());
if ( open_menu && open_menu != dd_menu )
if ( openmenu && openmenu != dd_menu )
{
open_menu->hide();
open_menu->hideSubMenus();
openmenu->hide();
openmenu->hideSubMenus();
}
if ( dialog_index )
@ -774,8 +771,8 @@ void FMenuItem::cb_switchToDialog (FWidget*, data_ptr data)
if ( win )
{
FWidget* focus_widget = getFocusWidget();
FAccelEvent a_ev (fc::Accelerator_Event, focus_widget);
FWidget* focus = getFocusWidget();
FAccelEvent a_ev (fc::Accelerator_Event, focus);
FApplication::sendEvent (win, &a_ev);
}
}

View File

@ -283,6 +283,14 @@ void FMouseGPM::processEvent (struct timeval*)
{
Gpm_FitEvent (&gpm_ev);
if ( ! hasSignificantEvents() )
{
GPM_DRAWPOINTER(&gpm_ev);
has_gpm_mouse_data = false;
mouse_event_occurred = false;
return;
}
if ( gpm_ev.type & GPM_DRAG && gpm_ev.wdx == 0 && gpm_ev.wdy == 0 )
b_state.mouse_moved = true;
@ -295,6 +303,84 @@ void FMouseGPM::processEvent (struct timeval*)
{
case GPM_DOWN:
case GPM_DRAG:
interpretKeyDown();
break;
case GPM_UP:
interpretKeyUp();
default:
break;
}
setPos (FPoint( std::max(gpm_ev.x, sInt16(1))
, std::max(gpm_ev.y, sInt16(1)) ));
if ( gpmEvent(false) == mouse_event )
input_data_pending = true;
else
input_data_pending = false;
GPM_DRAWPOINTER(&gpm_ev);
has_gpm_mouse_data = false;
mouse_event_occurred = true;
return;
}
else
gpm_fd = -1;
has_gpm_mouse_data = false;
mouse_event_occurred = false;
}
//----------------------------------------------------------------------
bool FMouseGPM::gpmMouse (bool on)
{
// activate/deactivate the gpm mouse support
if ( on )
{
Gpm_Connect conn;
conn.eventMask = uInt16(~0); // Get all including wheel event
conn.defaultMask = GPM_MOVE;
conn.maxMod = uInt16(~0);
conn.minMod = 0;
Gpm_Open(&conn, 0);
switch ( gpm_fd )
{
case -1: // error
return false;
case -2: // xterm is in use
return false;
default:
break;
}
}
else
{
Gpm_Close();
}
gpm_mouse_enabled = on;
return on;
}
//----------------------------------------------------------------------
bool FMouseGPM::hasSignificantEvents()
{
return ! (gpm_ev.type & GPM_MOVE)
|| gpm_ev.wdy != 0
|| gpm_ev.buttons & GPM_B_UP
|| gpm_ev.buttons & GPM_B_DOWN;
}
//----------------------------------------------------------------------
void FMouseGPM::interpretKeyDown()
{
if ( gpm_ev.buttons & GPM_B_LEFT )
{
if ( gpm_ev.type & GPM_DOUBLE )
@ -324,10 +410,11 @@ void FMouseGPM::processEvent (struct timeval*)
if ( gpm_ev.modifiers & (1 << KG_CTRL) )
b_state.control_button = true;
}
break;
case GPM_UP:
//----------------------------------------------------------------------
void FMouseGPM::interpretKeyUp()
{
if ( gpm_ev.buttons & GPM_B_LEFT )
b_state.left_button = Released;
@ -336,61 +423,6 @@ void FMouseGPM::processEvent (struct timeval*)
if ( gpm_ev.buttons & GPM_B_RIGHT )
b_state.right_button = Released;
default:
break;
}
setPos (FPoint(gpm_ev.x, gpm_ev.y));
if ( gpmEvent(false) == mouse_event )
input_data_pending = true;
else
input_data_pending = false;
GPM_DRAWPOINTER(&gpm_ev);
has_gpm_mouse_data = false;
mouse_event_occurred = true;
return;
}
has_gpm_mouse_data = false;
mouse_event_occurred = false;
}
//----------------------------------------------------------------------
bool FMouseGPM::gpmMouse (bool on)
{
// activate/deactivate the gpm mouse support
if ( on )
{
Gpm_Connect conn;
conn.eventMask = uInt16(~GPM_MOVE);
conn.defaultMask = GPM_MOVE;
conn.maxMod = uInt16(~0);
conn.minMod = 0;
Gpm_Open(&conn, 0);
switch ( gpm_fd )
{
case -1: // error
return false;
case -2: // xterm is in use
return false;
default:
break;
}
}
else
{
Gpm_Close();
}
gpm_mouse_enabled = on;
return on;
}
//----------------------------------------------------------------------
@ -1484,21 +1516,26 @@ bool FMouseControl::isInputDataPending()
}
//----------------------------------------------------------------------
#ifdef F_HAVE_LIBGPM
bool FMouseControl::isGpmMouseEnabled()
{
if ( mouse_protocol.empty() )
return false;
#ifdef F_HAVE_LIBGPM
FMouse* mouse = mouse_protocol[FMouse::gpm];
FMouseGPM* gpm_mouse = static_cast<FMouseGPM*>(mouse);
if ( gpm_mouse )
return gpm_mouse->isGpmMouseEnabled();
#endif // F_HAVE_LIBGPM
return false;
}
#else // F_HAVE_LIBGPM
bool FMouseControl::isGpmMouseEnabled()
{
return false;
}
#endif // F_HAVE_LIBGPM
//----------------------------------------------------------------------
void FMouseControl::enable()
@ -1559,43 +1596,43 @@ void FMouseControl::processEvent (struct timeval* time)
//----------------------------------------------------------------------
#ifdef F_HAVE_LIBGPM
bool FMouseControl::getGpmKeyPressed (bool pending)
#else
bool FMouseControl::getGpmKeyPressed (bool)
#endif // F_HAVE_LIBGPM
{
if ( mouse_protocol.empty() )
return false;
#ifdef F_HAVE_LIBGPM
FMouse* mouse = mouse_protocol[FMouse::gpm];
FMouseGPM* gpm_mouse = static_cast<FMouseGPM*>(mouse);
if ( gpm_mouse )
return gpm_mouse->getGpmKeyPressed(pending);
#endif // F_HAVE_LIBGPM
return false;
}
#else // F_HAVE_LIBGPM
bool FMouseControl::getGpmKeyPressed (bool)
{
return false;
}
#endif // F_HAVE_LIBGPM
//----------------------------------------------------------------------
#ifdef F_HAVE_LIBGPM
void FMouseControl::drawGpmPointer()
{
if ( mouse_protocol.empty() )
return;
#ifdef F_HAVE_LIBGPM
FMouse* mouse = mouse_protocol[FMouse::gpm];
FMouseGPM* gpm_mouse = static_cast<FMouseGPM*>(mouse);
if ( gpm_mouse )
gpm_mouse->drawGpmPointer();
#endif // F_HAVE_LIBGPM
}
#else // F_HAVE_LIBGPM
void FMouseControl::drawGpmPointer()
{ }
#endif // F_HAVE_LIBGPM
// private methods of FMouseControl

View File

@ -818,7 +818,7 @@ inline void FOptiMove::rightMove ( char hmove[], int& htime
{
std::strncpy ( hmove
, tparm(F_parm_right_cursor.cap, num, 0, 0, 0, 0, 0, 0, 0, 0)
, BUF_SIZE );
, BUF_SIZE - 1);
hmove[BUF_SIZE - 1] = '\0';
htime = F_parm_right_cursor.duration;
}
@ -938,7 +938,7 @@ inline bool FOptiMove::isMethod0Faster ( int& move_time
if ( move_xy )
{
char* move_ptr = move_buf;
std::strncpy (move_ptr, move_xy, BUF_SIZE);
std::strncpy (move_ptr, move_xy, BUF_SIZE - 1);
move_ptr[BUF_SIZE - 1] = '\0';
move_time = F_cursor_address.duration;
return true;

View File

@ -541,12 +541,12 @@ void FScrollView::onChildFocusIn (FFocusEvent*)
FRect widget_geometry;
FRect vp_geometry;
FWidget* focus_widget = FWidget::getFocusWidget();
FWidget* focus = FWidget::getFocusWidget();
if ( ! focus_widget )
if ( ! focus )
return;
widget_geometry = focus_widget->getGeometryWithShadow();
widget_geometry = focus->getGeometryWithShadow();
vp_geometry = viewport_geometry;
vp_geometry.move(1, 1);
@ -578,13 +578,13 @@ void FScrollView::onChildFocusOut (FFocusEvent* out_ev)
{
// Change the focus away from FScrollView to another widget
FWidget* focus_widget = FWidget::getFocusWidget();
FWidget* focus = FWidget::getFocusWidget();
if ( out_ev->getFocusType() == fc::FocusNextWidget )
{
FWidget* last_widget = getLastFocusableWidget(getChildren());
if ( focus_widget == last_widget )
if ( focus == last_widget )
{
out_ev->accept();
focusNextChild();
@ -594,7 +594,7 @@ void FScrollView::onChildFocusOut (FFocusEvent* out_ev)
{
FWidget* first_widget = getFirstFocusableWidget(getChildren());
if ( focus_widget == first_widget )
if ( focus == first_widget )
{
out_ev->accept();
focusPrevChild();

View File

@ -705,7 +705,7 @@ void FWindow::switchToPrevWindow (FWidget* widget_object)
widget_object->updateTerminal (FVTerm::stop_refresh);
bool is_activated = activatePrevWindow();
FWindow* active_window = static_cast<FWindow*>(getActiveWindow());
FWindow* active_win = static_cast<FWindow*>(getActiveWindow());
if ( ! is_activated )
{
@ -722,7 +722,7 @@ void FWindow::switchToPrevWindow (FWidget* widget_object)
FWindow* w = static_cast<FWindow*>(*iter);
if ( w
&& w != active_window
&& w != active_win
&& ! (w->isWindowHidden() || w->isWindowActive())
&& w != static_cast<FWindow*>(getStatusBar())
&& w != static_cast<FWindow*>(getMenuBar()) )
@ -735,19 +735,19 @@ void FWindow::switchToPrevWindow (FWidget* widget_object)
}
}
if ( active_window )
if ( active_win )
{
FWidget* focus_widget = active_window->getWindowFocusWidget();
FWidget* focus = active_win->getWindowFocusWidget();
if ( ! active_window->isWindowActive() )
setActiveWindow(active_window);
if ( ! active_win->isWindowActive() )
setActiveWindow(active_win);
if ( focus_widget )
if ( focus)
{
focus_widget->setFocus();
focus->setFocus();
if ( ! focus_widget->isWindowWidget() )
focus_widget->redraw();
if ( ! focus->isWindowWidget() )
focus->redraw();
}
}

View File

@ -217,6 +217,9 @@ class FMouseGPM : public FMouse
bool gpmMouse (bool);
bool enableGpmMouse();
bool disableGpmMouse();
bool hasSignificantEvents();
void interpretKeyDown();
void interpretKeyUp();
bool getGpmKeyPressed(bool);
void drawGpmPointer();