XQuartz: Add a defaults option to toggle Alt / Mode_switch

See option_sends_alt in Xquartz(1)

Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
Reviewed-by: Kevin Van Vechten <kvv@apple.com>
(cherry picked from commit 840d12c7a6)
This commit is contained in:
Jeremy Huddleston 2010-04-09 13:29:34 -07:00
parent af86a25009
commit a75e4be03c
9 changed files with 101 additions and 61 deletions

View File

@ -90,6 +90,7 @@ extern int quartzHasRoot, quartzEnableRootless, quartzFullscreenMenu;
#define PREFS_NO_TCP "nolisten_tcp"
#define PREFS_DONE_XINIT_CHECK "done_xinit_check"
#define PREFS_NO_QUIT_ALERT "no_quit_alert"
#define PREFS_OPTION_SENDS_ALT "option_sends_alt"
#define PREFS_FAKE_BUTTON2 "fake_button2"
#define PREFS_FAKE_BUTTON3 "fake_button3"
#define PREFS_APPKIT_MODIFIERS "appkit_modifiers"

View File

@ -712,10 +712,13 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
default:quartzEnableRootless];
quartzFullscreenMenu = [self prefs_get_boolean:@PREFS_FULLSCREEN_MENU
default:quartzFullscreenMenu];
quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:
@PREFS_FULLSCREEN_HOTKEYS default:!quartzFullscreenDisableHotkeys];
quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:@PREFS_FULLSCREEN_HOTKEYS
default:!quartzFullscreenDisableHotkeys];
darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
default:darwinFakeButtons];
quartzOptionSendsAlt = [self prefs_get_boolean:@PREFS_OPTION_SENDS_ALT
default:quartzOptionSendsAlt];
if (darwinFakeButtons) {
const char *fake2, *fake3;
@ -969,8 +972,7 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
fprintf(stderr, "X11ApplicationMain: Unable to determine KLGetCurrentKeyboardLayout() at startup.\n");
#endif
memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
if (!QuartzReadSystemKeymap(&keyInfo)) {
if (!QuartsResyncKeymap(FALSE)) {
fprintf(stderr, "X11ApplicationMain: Could not build a valid keymap.\n");
}
@ -1229,17 +1231,10 @@ static inline int ensure_flag(int flags, int device_independent, int device_depe
if(key_layout != last_key_layout) {
last_key_layout = key_layout;
#endif
/* Update keyInfo */
pthread_mutex_lock(&keyInfo_mutex);
memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
if (!QuartzReadSystemKeymap(&keyInfo)) {
if (!QuartsResyncKeymap(TRUE)) {
fprintf(stderr, "sendX11NSEvent: Could not build a valid keymap.\n");
}
pthread_mutex_unlock(&keyInfo_mutex);
/* Tell server thread to deal with new keyInfo */
DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
}
}

View File

@ -69,6 +69,7 @@ typedef unsigned int NSUInteger;
IBOutlet NSButton *use_sysbeep;
IBOutlet NSButton *enable_keyequivs;
IBOutlet NSButton *sync_keymap;
IBOutlet NSButton *option_sends_alt;
IBOutlet NSButton *click_through;
IBOutlet NSButton *focus_follows_mouse;
IBOutlet NSButton *focus_on_new_window;

View File

@ -43,6 +43,7 @@
#include "darwin.h"
#include "darwinEvents.h"
#include "quartz.h"
#include "quartzKeyboard.h"
#include <X11/extensions/applewmconst.h>
#include "applewmExt.h"
@ -630,49 +631,69 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
- (IBAction)prefs_changed:sender
{
BOOL pbproxy_active;
if(!sender)
return;
if(sender == fake_buttons) {
darwinFakeButtons = [fake_buttons intValue];
[NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
} else if(sender == use_sysbeep) {
quartzUseSysBeep = [use_sysbeep intValue];
[NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep];
} else if(sender == enable_keyequivs) {
X11EnableKeyEquivalents = [enable_keyequivs intValue];
[NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents];
} else if(sender == sync_keymap) {
darwinSyncKeymap = [sync_keymap intValue];
[NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
} else if(sender == enable_fullscreen_menu) {
quartzFullscreenMenu = [enable_fullscreen_menu intValue];
[NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:quartzFullscreenMenu];
} else if(sender == option_sends_alt) {
BOOL prev_opt_sends_alt = quartzOptionSendsAlt;
quartzOptionSendsAlt = [option_sends_alt intValue];
[NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:quartzOptionSendsAlt];
darwinFakeButtons = [fake_buttons intValue];
quartzUseSysBeep = [use_sysbeep intValue];
X11EnableKeyEquivalents = [enable_keyequivs intValue];
darwinSyncKeymap = [sync_keymap intValue];
quartzFullscreenMenu = [enable_fullscreen_menu intValue];
if(prev_opt_sends_alt != quartzOptionSendsAlt)
QuartsResyncKeymap(TRUE);
} else if(sender == click_through) {
[NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through intValue]];
} else if(sender == focus_follows_mouse) {
[NSApp prefs_set_boolean:@PREFS_FFM value:[focus_follows_mouse intValue]];
} else if(sender == focus_on_new_window) {
[NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:[focus_on_new_window intValue]];
} else if(sender == enable_auth) {
[NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]];
} else if(sender == enable_tcp) {
[NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]];
} else if(sender == depth) {
[NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]];
} else if(sender == sync_pasteboard) {
BOOL pbproxy_active = [sync_pasteboard intValue];
[NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active];
/* after adding prefs here, also add to [X11Application read_defaults]
and prefs_show */
[sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[sync_pasteboard_to_primary setEnabled:pbproxy_active];
[sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
[sync_primary_immediately setEnabled:pbproxy_active];
[NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
[NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep];
[NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents];
[NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
[NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:quartzFullscreenMenu];
[NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through intValue]];
[NSApp prefs_set_boolean:@PREFS_FFM value:[focus_follows_mouse intValue]];
[NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:[focus_on_new_window intValue]];
[NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]];
[NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]];
[NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]];
pbproxy_active = [sync_pasteboard intValue];
[NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active];
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:[sync_pasteboard_to_clipboard intValue]];
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:[sync_pasteboard_to_primary intValue]];
[NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:[sync_clipboard_to_pasteboard intValue]];
[NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:[sync_primary_immediately intValue]];
// setEnabled doesn't do this...
[sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
[sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
} else if(sender == sync_pasteboard_to_clipboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:[sync_pasteboard_to_clipboard intValue]];
} else if(sender == sync_pasteboard_to_primary) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:[sync_pasteboard_to_primary intValue]];
} else if(sender == sync_clipboard_to_pasteboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:[sync_clipboard_to_pasteboard intValue]];
} else if(sender == sync_primary_immediately) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:[sync_primary_immediately intValue]];
}
[NSApp prefs_synchronize];
[sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[sync_pasteboard_to_primary setEnabled:pbproxy_active];
[sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
[sync_primary_immediately setEnabled:pbproxy_active];
// setEnabled doesn't do this...
[sync_text1 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
[sync_text2 setTextColor:pbproxy_active ? [NSColor controlTextColor] : [NSColor disabledControlTextColor]];
DarwinSendDDXEvent(kXquartzReloadPreferences, 0);
DarwinSendDDXEvent(kXquartzReloadPreferences, 0);
}
- (IBAction) prefs_show:sender
@ -683,6 +704,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
[use_sysbeep setIntValue:quartzUseSysBeep];
[enable_keyequivs setIntValue:X11EnableKeyEquivalents];
[sync_keymap setIntValue:darwinSyncKeymap];
[option_sends_alt setIntValue:quartzOptionSendsAlt];
[click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]];
[focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]];
[focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]];

View File

@ -63,6 +63,9 @@ defaults to the depth of the main display.
.B defaults write org.x.X11 sync_keymap -boolean true
Keep the X11 keymap up to date with the OSX system keymap.
.TP 8
.B defaults write org.x.X11 option_sends_alt -boolean true
The Option key will send Alt_L and Alt_R instead of Mode_switch.
.TP 8
.B defaults write org.x.X11 sync_pasteboard -boolean true
Enable syncing between the OSX pasteboard and clipboard/primary selection buffers in X11. This option needs to be true for any of the other pasteboard sync options to have an effect.
.TP 8

View File

@ -79,6 +79,7 @@ int aquaMenuBarHeight = 0;
QuartzModeProcsPtr quartzProcs = NULL;
const char *quartzOpenGLBundle = NULL;
int quartzFullscreenDisableHotkeys = TRUE;
int quartzOptionSendsAlt = FALSE;
#if defined(RANDR) && !defined(FAKE_RANDR)
Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {

View File

@ -60,6 +60,7 @@ extern int focusOnNewWindow;
extern int quartzUseAGL;
extern int quartzEnableKeyEquivalents;
extern int quartzFullscreenDisableHotkeys;
extern int quartzOptionSendsAlt;
// Other shared data
extern int quartzServerVisible;

View File

@ -50,6 +50,7 @@
#include "quartzCommon.h"
#include "darwin.h"
#include "darwinEvents.h"
#include "quartzKeyboard.h"
#include "quartzAudio.h"
@ -191,6 +192,12 @@ const static struct {
{UKEYSYM (0x31b), XK_dead_horn}, /* COMBINING HORN */
};
typedef struct darwinKeyboardInfo_struct {
CARD8 modMap[MAP_LENGTH];
KeySym keyMap[MAP_LENGTH * GLYPHS_PER_KEY];
unsigned char modifierKeycodes[32][2];
} darwinKeyboardInfo;
darwinKeyboardInfo keyInfo;
pthread_mutex_t keyInfo_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -255,7 +262,8 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
case XK_Alt_L:
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
info->modMap[MIN_KEYCODE + i] = Mod1Mask;
*k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
if(!quartzOptionSendsAlt)
*k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
break;
case XK_Alt_R:
@ -264,7 +272,8 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
#else
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
#endif
*k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
if(!quartzOptionSendsAlt)
*k = XK_Mode_switch; // Yes, this is ugly. This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.
info->modMap[MIN_KEYCODE + i] = Mod1Mask;
break;
@ -647,7 +656,7 @@ static KeySym make_dead_key(KeySym in) {
return in;
}
Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) {
static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) {
#if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050
KeyboardLayoutRef key_layout;
int is_uchr = 1;
@ -824,3 +833,18 @@ Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) {
return TRUE;
}
Bool QuartsResyncKeymap(Bool sendDDXEvent) {
Bool retval;
/* Update keyInfo */
pthread_mutex_lock(&keyInfo_mutex);
memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
retval = QuartzReadSystemKeymap(&keyInfo);
pthread_mutex_unlock(&keyInfo_mutex);
/* Tell server thread to deal with new keyInfo */
if(sendDDXEvent)
DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
return retval;
}

View File

@ -41,18 +41,10 @@
#define MIN_KEYCODE XkbMinLegalKeyCode // unfortunately, this isn't 0...
#define MAX_KEYCODE NUM_KEYCODES + MIN_KEYCODE - 1
typedef struct darwinKeyboardInfo_struct {
CARD8 modMap[MAP_LENGTH];
KeySym keyMap[MAP_LENGTH * GLYPHS_PER_KEY];
unsigned char modifierKeycodes[32][2];
} darwinKeyboardInfo;
/* These functions need to be implemented by Xquartz, XDarwin, etc. */
Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info);
Bool QuartsResyncKeymap(Bool sendDDXEvent);
/* Provided for darwinEvents.c */
extern darwinKeyboardInfo keyInfo;
extern pthread_mutex_t keyInfo_mutex;
void DarwinKeyboardReloadHandler(void);
int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide);
int DarwinModifierNXKeyToNXKeycode(int key, int side);