XQuartz: Made 3-button mouse simulation a little more consistent.
(cherry picked from commit d207b037d2ae213369e5627a17d8831c9bc16ad8)
This commit is contained in:
parent
f51f77d25e
commit
1770c85374
|
@ -77,7 +77,7 @@ in this Software without prior written authorization from The Open Group.
|
||||||
/* FIXME: Abstract this better */
|
/* FIXME: Abstract this better */
|
||||||
void QuartzModeEQInit(void);
|
void QuartzModeEQInit(void);
|
||||||
|
|
||||||
static int old_flags = 0; // last known modifier state
|
static int modifier_flags = 0; // last known modifier state
|
||||||
|
|
||||||
#define FD_ADD_MAX 128
|
#define FD_ADD_MAX 128
|
||||||
static int fd_add[FD_ADD_MAX];
|
static int fd_add[FD_ADD_MAX];
|
||||||
|
@ -140,19 +140,19 @@ static inline void darwinEvents_unlock(void) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DarwinPressModifierMask
|
* DarwinPressModifierMask
|
||||||
* Press or release the given modifier key, specified by its mask.
|
* Press or release the given modifier key, specified by its mask (one of NX_*MASK constants)
|
||||||
*/
|
*/
|
||||||
static void DarwinPressModifierMask(
|
static void DarwinPressModifierMask(int pressed, int mask) {
|
||||||
int pressed,
|
int keycode;
|
||||||
int mask) // one of NX_*MASK constants
|
|
||||||
{
|
|
||||||
int key = DarwinModifierNXMaskToNXKey(mask);
|
int key = DarwinModifierNXMaskToNXKey(mask);
|
||||||
|
|
||||||
if (key != -1) {
|
if (key != -1) {
|
||||||
int keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
|
keycode = DarwinModifierNXKeyToNXKeycode(key, 0);
|
||||||
if (keycode != 0)
|
if (keycode != 0)
|
||||||
DarwinSendKeyboardEvents(pressed, keycode);
|
DarwinSendKeyboardEvents(pressed, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorF("DarwinPressModifierMask pressed=%s, mask=%d, key=%d, keycode=%d\n", pressed == KeyPress ? "press" : "release", mask, key, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NX_DEVICELCTLKEYMASK
|
#ifdef NX_DEVICELCTLKEYMASK
|
||||||
|
@ -187,6 +187,8 @@ static void DarwinUpdateModifiers(
|
||||||
int pressed, // KeyPress or KeyRelease
|
int pressed, // KeyPress or KeyRelease
|
||||||
int flags ) // modifier flags that have changed
|
int flags ) // modifier flags that have changed
|
||||||
{
|
{
|
||||||
|
fprintf(stderr, "DarwinUpdateModifiers pressed=%s, flags=%x\n", pressed == KeyPress ? "press" : "release", flags);
|
||||||
|
|
||||||
if (flags & NX_ALPHASHIFTMASK) {
|
if (flags & NX_ALPHASHIFTMASK) {
|
||||||
DarwinPressModifierMask(pressed, NX_ALPHASHIFTMASK);
|
DarwinPressModifierMask(pressed, NX_ALPHASHIFTMASK);
|
||||||
}
|
}
|
||||||
|
@ -214,45 +216,10 @@ static void DarwinUpdateModifiers(
|
||||||
* are held down during a "context" switch -- otherwise, we would miss the KeyUp.
|
* are held down during a "context" switch -- otherwise, we would miss the KeyUp.
|
||||||
*/
|
*/
|
||||||
static void DarwinReleaseModifiers(void) {
|
static void DarwinReleaseModifiers(void) {
|
||||||
|
ErrorF("DarwinReleaseModifiers\n");
|
||||||
DarwinUpdateModifiers(KeyRelease, COMMAND_MASK(-1) | CONTROL_MASK(-1) | ALTERNATE_MASK(-1) | SHIFT_MASK(-1));
|
DarwinUpdateModifiers(KeyRelease, COMMAND_MASK(-1) | CONTROL_MASK(-1) | ALTERNATE_MASK(-1) | SHIFT_MASK(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* DarwinSimulateMouseClick
|
|
||||||
* Send a mouse click to X when multiple mouse buttons are simulated
|
|
||||||
* with modifier-clicks, such as command-click for button 2. The dix
|
|
||||||
* layer is told that the previously pressed modifier key(s) are
|
|
||||||
* released, the simulated click event is sent. After the mouse button
|
|
||||||
* is released, the modifier keys are reverted to their actual state,
|
|
||||||
* which may or may not be pressed at that point. This is usually
|
|
||||||
* closest to what the user wants. Ie. the user typically wants to
|
|
||||||
* simulate a button 2 press instead of Command-button 2.
|
|
||||||
*/
|
|
||||||
static void DarwinSimulateMouseClick(
|
|
||||||
int pointer_x,
|
|
||||||
int pointer_y,
|
|
||||||
float pressure,
|
|
||||||
float tilt_x,
|
|
||||||
float tilt_y,
|
|
||||||
int whichButton, // mouse button to be pressed
|
|
||||||
int modifierMask) // modifiers used for the fake click
|
|
||||||
{
|
|
||||||
// first fool X into forgetting about the keys
|
|
||||||
// for some reason, it's not enough to tell X we released the Command key --
|
|
||||||
// it has to be the *left* Command key.
|
|
||||||
if (modifierMask & NX_COMMANDMASK) modifierMask |=NX_DEVICELCMDKEYMASK ;
|
|
||||||
DarwinUpdateModifiers(KeyRelease, modifierMask);
|
|
||||||
|
|
||||||
// push the mouse button
|
|
||||||
DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y,
|
|
||||||
pressure, tilt_x, tilt_y);
|
|
||||||
DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y,
|
|
||||||
pressure, tilt_x, tilt_y);
|
|
||||||
|
|
||||||
// restore old modifiers
|
|
||||||
DarwinUpdateModifiers(KeyPress, modifierMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generic handler for Xquartz-specifc events. When possible, these should
|
/* Generic handler for Xquartz-specifc events. When possible, these should
|
||||||
be moved into their own individual functions and set as handlers using
|
be moved into their own individual functions and set as handlers using
|
||||||
mieqSetHandler. */
|
mieqSetHandler. */
|
||||||
|
@ -475,7 +442,6 @@ static void DarwinPrepareValuators(int *valuators, ScreenPtr screen,
|
||||||
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
|
void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y,
|
||||||
float pressure, float tilt_x, float tilt_y) {
|
float pressure, float tilt_x, float tilt_y) {
|
||||||
static int darwinFakeMouseButtonDown = 0;
|
static int darwinFakeMouseButtonDown = 0;
|
||||||
static int darwinFakeMouseButtonMask = 0;
|
|
||||||
int i, num_events;
|
int i, num_events;
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
ScreenPtr screen;
|
ScreenPtr screen;
|
||||||
|
@ -499,35 +465,27 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle fake click */
|
||||||
if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) {
|
if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) {
|
||||||
// Mimic multi-button mouse with modifier-clicks
|
if(darwinFakeMouseButtonDown != 0) {
|
||||||
// If both sets of modifiers are pressed,
|
/* We're currently "down" with another button, so release it first */
|
||||||
// button 2 is clicked.
|
DarwinSendPointerEvents(ButtonRelease, darwinFakeMouseButtonDown, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
|
||||||
if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) {
|
darwinFakeMouseButtonDown=0;
|
||||||
DarwinSimulateMouseClick(pointer_x, pointer_y, pressure,
|
}
|
||||||
tilt_x, tilt_y, 2, darwinFakeMouse2Mask);
|
if ((modifier_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) {
|
||||||
|
ev_button = 2;
|
||||||
darwinFakeMouseButtonDown = 2;
|
darwinFakeMouseButtonDown = 2;
|
||||||
darwinFakeMouseButtonMask = darwinFakeMouse2Mask;
|
} else if ((modifier_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) {
|
||||||
return;
|
ev_button = 3;
|
||||||
} else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) {
|
|
||||||
DarwinSimulateMouseClick(pointer_x, pointer_y, pressure,
|
|
||||||
tilt_x, tilt_y, 3, darwinFakeMouse3Mask);
|
|
||||||
darwinFakeMouseButtonDown = 3;
|
darwinFakeMouseButtonDown = 3;
|
||||||
darwinFakeMouseButtonMask = darwinFakeMouse3Mask;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev_type == ButtonRelease && darwinFakeButtons && darwinFakeMouseButtonDown) {
|
if (ev_type == ButtonRelease && ev_button == 1) {
|
||||||
// If last mousedown was a fake click, don't check for
|
if(darwinFakeMouseButtonDown) {
|
||||||
// mouse modifiers here. The user may have released the
|
ev_button = darwinFakeMouseButtonDown;
|
||||||
// modifiers before the mouse button.
|
darwinFakeMouseButtonDown = 0;
|
||||||
ev_button = darwinFakeMouseButtonDown;
|
}
|
||||||
darwinFakeMouseButtonDown = 0;
|
|
||||||
// Bring modifiers back up to date
|
|
||||||
DarwinUpdateModifiers(KeyPress, darwinFakeMouseButtonMask & old_flags);
|
|
||||||
darwinFakeMouseButtonMask = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DarwinPrepareValuators(valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
|
DarwinPrepareValuators(valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
|
||||||
|
@ -547,7 +505,7 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) {
|
if (modifier_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) {
|
||||||
/* See if keymap has changed. */
|
/* See if keymap has changed. */
|
||||||
|
|
||||||
static unsigned int last_seed;
|
static unsigned int last_seed;
|
||||||
|
@ -627,9 +585,9 @@ void DarwinSendScrollEvents(float count_x, float count_y,
|
||||||
/* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to
|
/* Send the appropriate KeyPress/KeyRelease events to GetKeyboardEvents to
|
||||||
reflect changing modifier flags (alt, control, meta, etc) */
|
reflect changing modifier flags (alt, control, meta, etc) */
|
||||||
void DarwinUpdateModKeys(int flags) {
|
void DarwinUpdateModKeys(int flags) {
|
||||||
DarwinUpdateModifiers(KeyRelease, old_flags & ~flags);
|
DarwinUpdateModifiers(KeyRelease, modifier_flags & ~flags);
|
||||||
DarwinUpdateModifiers(KeyPress, ~old_flags & flags);
|
DarwinUpdateModifiers(KeyPress, ~modifier_flags & flags);
|
||||||
old_flags = flags;
|
modifier_flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue