X11: Как НАИСТИНА да хвана показалеца на мишката?

Внедрих джаджа за хоризонтален разделител в Xlib. Опитвам се да хвана мишката, когато потребителят щракне и плъзне върху лентата за разделяне (така че потребителят да може динамично да премести разделянето и по този начин да преоразмери прозорците от двете страни на лентата за разделяне).

Използвах XGrabPointer() след щракване с ляв бутон, с надеждата, че всички бъдещи движения на мишката (плъзгане) ще бъдат пренасочени към прозореца на разделителя, докато левият бутон не бъде освободен.

За съжаление, изглежда, че не работи така. Ако потребителят плъзга твърде бързо и показалецът на мишката влезе в един от прозорците от двете страни на разделянето, съобщенията за MotionEvent се пренасочват към този (дете) прозорец, а не към прозореца на разделителя.

Какво съм направил грешно? Моето XGrabPointer() обаждане е както следва:

::XGrabPointer(mDisplay, window, True,
               ButtonPressMask |
                 ButtonReleaseMask |
                 PointerMotionMask |
                 FocusChangeMask |
                 EnterWindowMask |
                  LeaveWindowMask,
               GrabModeAsync,
               GrabModeAsync,
               RootWindow(mDisplay, DefaultScreen(mDisplay)),
               None,
               CurrentTime);

person Drew Hall    schedule 08.05.2010    source източник


Отговори (1)


Почти ме е неудобно да призная това, но отговорът се оказа толкова прост, колкото промяната на този трети параметър (owner_events) от True на False.

От урок/референция за Xlib на tronche.com:

Ако owner_events е False, всички генерирани указателни събития се отчитат по отношение на grab_window и се отчитат само ако са избрани от event_mask. Ако owner_events е True и ако генерирано указателно събитие обикновено се докладва на този клиент, то се докладва както обикновено. В противен случай събитието се отчита по отношение на grab_window и се отчита само ако е избрано от event_mask.

Все още не съм сигурен, че разбирам напълно поведението на случая True, но моето тълкуване е, че ако True, други X програми (т.е. прозорци, създадени от други процеси) са забранени да получават XEvents, но тези, които биха ударили всеки прозорец създадени от вашия процес, се доставят както обикновено. В грешния случай всички събития се отчитат по отношение на конкретния прозорец, който сте избрали. Това беше поведението, което преследвах.

person Drew Hall    schedule 08.05.2010
comment
Ако контекстното меню е отворено (обикновено след право щракване), XGrabPointer() връща alreadyGrabbed и нямам представа как да възстановя възможността за хващане на мишката. Можете ли да ми дадете някакъв съвет? - person ezain; 21.06.2019