как победить плаванье onMouseMove
Модератор: Модераторы
как победить плаванье onMouseMove
В графическом приложении по onMouseMove нужно перерисовывать экран.
Под виндой всё работает нормально - виндовс не добавляет новых сообщений от мышки если старые еще не обработаны.
Под линуксом сообщения добавляются всегда, даже если приложение занято (нуспело перерисоваться) - сообщения копятся, мышка плавает.
Попробовал в onMouseMove только запоминать координаты, а перерисовывать в onIdle - курсор чуток подергивается - это конечно лучше чем плавает, но тоже негодится.
Как правильно организовать onMouseMove в моем случае? или как попросить GTK чтоб он вел себя как WIN?
Под виндой всё работает нормально - виндовс не добавляет новых сообщений от мышки если старые еще не обработаны.
Под линуксом сообщения добавляются всегда, даже если приложение занято (нуспело перерисоваться) - сообщения копятся, мышка плавает.
Попробовал в onMouseMove только запоминать координаты, а перерисовывать в onIdle - курсор чуток подергивается - это конечно лучше чем плавает, но тоже негодится.
Как правильно организовать onMouseMove в моем случае? или как попросить GTK чтоб он вел себя как WIN?
Последний раз редактировалось zub 02.09.2010 01:35:29, всего редактировалось 1 раз.
Re: как победить торможение onMouseMove
ну это надо сильно извратиться, чтобы GTK о ТАКОМ попросить.
попробуйте GTK2, к примеру.
или же перерисовывайте по таймеру.
или же по IdleTimer'у, что в вашем случае имхо больше подходит, чем по просто-таймеру.
попробуйте GTK2, к примеру.
или же перерисовывайте по таймеру.
или же по IdleTimer'у, что в вашем случае имхо больше подходит, чем по просто-таймеру.
Re: как победить торможение onMouseMove
>>попробуйте GTK2, к примеру.
да, я имел ввиду GTK2. можно подробнее про возможность настройки обработки мыши?
>>или же перерисовывайте по таймеру.
В смысле по таймеру смотреть было ли движение мышки и рисовать? помоеему всеравно будет дергаться
да, я имел ввиду GTK2. можно подробнее про возможность настройки обработки мыши?
>>или же перерисовывайте по таймеру.
В смысле по таймеру смотреть было ли движение мышки и рисовать? помоеему всеравно будет дергаться
Re: как победить торможение onMouseMove
Таймер ИМХО тут будет лишним.
как я понял мне должно помочь вот это: http://mirror.linuxiso.kz/linfoline.hom ... x2447.html
Как это будет выглядеть на LCL?
как я понял мне должно помочь вот это: http://mirror.linuxiso.kz/linfoline.hom ... x2447.html
Для нашей программмы рисования, мы должны знать, когда кнопка мыши нажата и мышь перемещена, таким образом мы определяем GDK_POINTER_MOTION_MASK и GDK_BUTTON_PRESS_MASK. Мы также должны знать, когда перерисовать наше окно, таким образом мы определяем GDK_EXPOSURE_MASK. Хотя нам необходимо уведомление об изменении размера нашего окна через конфигурацию события, мы не должны определять передачу флага GDK_STRUCTURE_MASK, потому что это автоматически определено для всех окон.
Однако, как оказывается есть проблема с определением GDK_POINTER_MOTION_MASK. Это заставит сервер добавлять новое событие передвижения в очередь событий каждый раз, когда пользователь перемещает мышь. Вообразите, что нам требуется 0.1 секунды, чтобы обработать событие движения, но в очередь X сервера поступает новое событие передвижения каждые 0.05 секунды. Если пользователь рисовал в течении 5 секунд, нам потребуется ещё 5 секунд для перехвата после освобождения кнопки мышки! Но нам нужно получить только одно событие движения для каждого случая, который мы обрабатываем. Это можно сделать определив GDK_POINTER_MOTION_HINT_MASK.
Мы определяем GDK_POINTER_MOTION_HINT_MASK, когда сервер в первый раз сообщает нам о передвижении указателя после входа в наше окно, или после нажатия или освобождения кнопки. Последующие события движения будут подавлены, пока мы явно не спросим положение указателя, используя функцию:Код: Выделить всё
GdkWindow* gdk_window_get_pointer (GdkWindow *window,
gint *x,
gint *y,
GdkModifierType *mask);
и сам обработчик:Код: Выделить всё
static gint
motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
{
int x, y;
GdkModifierType state;
if (event->is_hint)
gdk_window_get_pointer (event->window, &x, &y, &state);
else
{
x = event->x;
y = event->y;
state = event->state;
}
if (state & GDK_BUTTON1_MASK && pixmap != NULL)
draw_brush (widget, x, y);
return TRUE;
}
Как это будет выглядеть на LCL?
Re: как победить торможение onMouseMove
попробовал перерисовывать мышку по таймеру - на интервале >10 - дергается, на интервале <10 начинает плавать.
попробовал в обычном onMouseMove запускать перерисовку только если XPending возвращает 0 - тоже дергается, хотя меньше чем перерисовка в onIdle
>>Как это будет выглядеть на LCL?
следов GDK_POINTER_MOTION_HINT_MASK в LCL мои ковыряния (в исходниках и в гугле) не выявили... неужели никто не сталкивался с этой проблемой? как прикрутить GDK_POINTER_MOTION_HINT_MASK к TOpenGLControl не лазя в исходники LCL?
попробовал в обычном onMouseMove запускать перерисовку только если XPending возвращает 0 - тоже дергается, хотя меньше чем перерисовка в onIdle
>>Как это будет выглядеть на LCL?
следов GDK_POINTER_MOTION_HINT_MASK в LCL мои ковыряния (в исходниках и в гугле) не выявили... неужели никто не сталкивался с этой проблемой? как прикрутить GDK_POINTER_MOTION_HINT_MASK к TOpenGLControl не лазя в исходники LCL?
Re: как победить торможение onMouseMove
zub писал(а):неужели никто не сталкивался с этой проблемой? как прикрутить GDK_POINTER_MOTION_HINT_MASK к TOpenGLControl не лазя в исходники LCL?
Это нетиповая задача. Если она и решается, то в обход принципов работы LCL. Т.е. вряд ли кто-то даст гарантии, что найденный способ не сломается через несколько десятков ревизий. LCL разрабатывалась именно для того, чтобы изолировать разработчика от GTK/Qt/WinAPI. Поэтому без погружения в её исходники тут вряд ли получится обойтись.
Re: как победить торможение onMouseMove
Qt версия работает точно также, насколько понял это особенность X Window. Это дело учтено даже в GTK примере к FPC - scribble, странно (ИМХО) что в LCL момент остался без внимания.
>>Т.е. вряд ли кто-то даст гарантии, что найденный способ не сломается через несколько десятков ревизий
>>Поэтому без погружения в её исходники тут вряд ли получится обойтись.
Собственно гарантий ненадо, и погрузиться я не против, лишбы без их изменения. Ну и ткнуться носом куда копать
Добавлено спустя 17 часов 38 минут 24 секунды:
Re: как победить плаванье onMouseMove
странно, но оказалось достаточно подписать окно на GDK_POINTER_MOTION_HINT_MASK
и всё заработало рово
>>Т.е. вряд ли кто-то даст гарантии, что найденный способ не сломается через несколько десятков ревизий
>>Поэтому без погружения в её исходники тут вряд ли получится обойтись.
Собственно гарантий ненадо, и погрузиться я не против, лишбы без их изменения. Ну и ткнуться носом куда копать
Добавлено спустя 17 часов 38 минут 24 секунды:
Re: как победить плаванье onMouseMove
странно, но оказалось достаточно подписать окно на GDK_POINTER_MOTION_HINT_MASK
Код: Выделить всё
gtk_widget_add_events (Widget,GDK_POINTER_MOTION_HINT_MASK);и всё заработало рово
Re: как победить плаванье onMouseMove
>>и всё заработало рово
Блин, не заработало ровно... Подергивания всеравно присутствуют, просто стали поменьше. Визуально при скролинге мышью в линуксе видны рывки, в винде всё идеально...
В программе рисуется свой курсор (вертикальное перекрестие во всю рабочую область), для теста я отключил стирание фона - неровная обработка мышки (выподение сообщений - отсутствие вертикальных полос) явно видна на линуксовом скриншоте:
а вот в винде:
Добавлено спустя 13 минут 50 секунд:
Мышку двигал с приблизительно одинаковой скоростью (быстро), комп один и тотже, но в линуксе почемуто события от мышки приходят гораздо чаще. Видимо вся эта беда связана с нестабильным временем затраченым на обновлением экрана средствами OpenGL, под виндой это стабильно 10-15мсек (очень редко 0.5мсек), под линуксом всегда прыгает 0.2-1мсек. замерено rdtsc на одноядерном проце.
Блин, не заработало ровно... Подергивания всеравно присутствуют, просто стали поменьше. Визуально при скролинге мышью в линуксе видны рывки, в винде всё идеально...
В программе рисуется свой курсор (вертикальное перекрестие во всю рабочую область), для теста я отключил стирание фона - неровная обработка мышки (выподение сообщений - отсутствие вертикальных полос) явно видна на линуксовом скриншоте:
а вот в винде:
Добавлено спустя 13 минут 50 секунд:
Мышку двигал с приблизительно одинаковой скоростью (быстро), комп один и тотже, но в линуксе почемуто события от мышки приходят гораздо чаще. Видимо вся эта беда связана с нестабильным временем затраченым на обновлением экрана средствами OpenGL, под виндой это стабильно 10-15мсек (очень редко 0.5мсек), под линуксом всегда прыгает 0.2-1мсек. замерено rdtsc на одноядерном проце.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Re: как победить плаванье onMouseMove
Совершенно случайно обнаружил - мышку подергивает когда фоном запущена опера... и почемута эта подлая опера отъедает 10-20-30% cpu даже ничего не отображая...
если запускать программу в гордом одиночестве - всё нормально! надо завязывать лазать на freepascal.ru во время отладки))
если запускать программу в гордом одиночестве - всё нормально! надо завязывать лазать на freepascal.ru во время отладки))
Re: как победить плаванье onMouseMove
надо завязывать лазать на freepascal.ru во время отладки))
можно заюзать фаерфокс, который будет жрать память, а не цпу, что положительно скажется на тестах
Re: как победить торможение onMouseMove
zub писал(а):странно, но оказалось достаточно подписать окно на GDK_POINTER_MOTION_HINT_MASKКод: Выделить всё
gtk_widget_add_events (Widget,GDK_POINTER_MOTION_HINT_MASK);
и всё заработало ровно
многоуважаемый zub не могли бы вы привести пример использования этой функции именно для проекта в lazarus.
Re: как победить плаванье onMouseMove
У меня так:
возможно в uses чтото лишнее, не проверял. Вызываю один раз при инициализации OpenGL
Код: Выделить всё
uses
......
x,xlib,
gtk2,gdk2,
......
gtk_widget_add_events (PGtkWidget(PtrUInt(Handle)),GDK_POINTER_MOTION_HINT_MASK);возможно в uses чтото лишнее, не проверял. Вызываю один раз при инициализации OpenGL
Re: как победить плаванье onMouseMove
Спасибо))
Re: как победить плаванье onMouseMove
Незачто))
наконецто допер окончательно в чем дело
плаванье мышки полечилось gtk_widget_add_events (или асинхронной перерисовкой, вне onMouseMove - оба варианта работают хорошо), а дерганость отключением эффектов рабочего стола
Сами конкретные эффекты были все выключены, стояла лишь общая галка "использовать эффекты раб.стола", что нехило придушивало мое приложение. Теперь мышиноопенгльный тест под линуксом выглядит так: короткий разбег, ровная беготня, торможение об противоположную стенку монитора. Юзать программу в линуксе стало приятней чем в винде, независимо от того сколько опер и прочей лабуды запущено фоном)), осталось ее дописать.
наконецто допер окончательно в чем дело
плаванье мышки полечилось gtk_widget_add_events (или асинхронной перерисовкой, вне onMouseMove - оба варианта работают хорошо), а дерганость отключением эффектов рабочего стола
Сами конкретные эффекты были все выключены, стояла лишь общая галка "использовать эффекты раб.стола", что нехило придушивало мое приложение. Теперь мышиноопенгльный тест под линуксом выглядит так: короткий разбег, ровная беготня, торможение об противоположную стенку монитора. Юзать программу в линуксе стало приятней чем в винде, независимо от того сколько опер и прочей лабуды запущено фоном)), осталось ее дописать.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
