// Hotkeys.C // If you want to change what the hotkeys are, see the table at the bottom! #include "config.h" #include "Frame.H" #include "Desktop.H" #include extern void ShowMenu(); extern void ShowTabMenu(int tab); #if STANDARD_HOTKEYS static void NextWindow() { // Alt+Tab ShowTabMenu(1); } static void PreviousWindow() { // Alt+Shift+Tab ShowTabMenu(-1); } #endif #if DESKTOPS static void NextDesk() { if (Desktop::current()) { Desktop::current(Desktop::current()->next? Desktop::current()->next:Desktop::first); } else { Desktop::current(Desktop::first); } } static void PreviousDesk() { Desktop* search=Desktop::first; while (search->next && search->next!=Desktop::current()){ search=search->next; } Desktop::current(search); } // warning: this assummes it is bound to Fn key: static void DeskNumber() { Desktop::current(Desktop::number(Fl::event_key()-FL_F, 1)); } #endif #if WMX_HOTKEYS || CDE_HOTKEYS static void Raise() { // Alt+Up Frame* f = Frame::activeFrame(); if (f) f->raise(); } static void Lower() { // Alt+Down Frame* f = Frame::activeFrame(); if (f) f->lower(); } static void Iconize() { // Alt+Enter Frame* f = Frame::activeFrame(); if (f) f->iconize(); else ShowMenu(); // so they can deiconize stuff } static void Close() { // Alt+Delete Frame* f = Frame::activeFrame(); if (f) f->close(); } #endif //////////////////////////////////////////////////////////////// static struct {int key; void (*func)();} keybindings[] = { #if STANDARD_HOTKEYS || MINIMUM_HOTKEYS // these are very common and tend not to conflict, due to Windoze: {FL_ALT+FL_Escape, ShowMenu}, {FL_ALT+FL_Menu, ShowMenu}, #endif #if STANDARD_HOTKEYS {FL_ALT+FL_Tab, NextWindow}, {FL_ALT+FL_SHIFT+FL_Tab,PreviousWindow}, {FL_ALT+FL_SHIFT+0xfe20,PreviousWindow}, // XK_ISO_Left_Tab #endif #if KWM_HOTKEYS && DESKTOPS // KWM uses these to switch desktops // {FL_CTRL+FL_Tab, NextDesk}, // {FL_CTRL+FL_SHIFT+FL_Tab,PreviousDesk}, // {FL_CTRL+FL_SHIFT+0xfe20,PreviousDesk}, // XK_ISO_Left_Tab {FL_CTRL+FL_F+1, DeskNumber}, {FL_CTRL+FL_F+2, DeskNumber}, {FL_CTRL+FL_F+3, DeskNumber}, {FL_CTRL+FL_F+4, DeskNumber}, {FL_CTRL+FL_F+5, DeskNumber}, {FL_CTRL+FL_F+6, DeskNumber}, {FL_CTRL+FL_F+7, DeskNumber}, {FL_CTRL+FL_F+8, DeskNumber}, {FL_CTRL+FL_F+9, DeskNumber}, {FL_CTRL+FL_F+10, DeskNumber}, {FL_CTRL+FL_F+11, DeskNumber}, {FL_CTRL+FL_F+12, DeskNumber}, #endif #if WMX_HOTKEYS // wmx also sets all these, they seem pretty useful: {FL_ALT+FL_Up, Raise}, {FL_ALT+FL_Down, Lower}, {FL_ALT+FL_Enter, Iconize}, {FL_ALT+FL_Delete, Close}, //{FL_ALT+FL_Page_Up, ToggleMaxH}, //{FL_ALT+FL_Page_Down,ToggleMaxW}, #endif #if WMX_DESK_HOTKEYS && DESKTOPS // these wmx keys are not set by default as they break NetScape: {FL_ALT+FL_Left, PreviousDesk}, {FL_ALT+FL_Right, NextDesk}, #endif #if CDE_HOTKEYS // CDE hotkeys (or at least what SGI's 4DWM uses): {FL_ALT+FL_F+1, Raise}, //{FL_ALT+FL_F+2, unknown}, // KWM uses this to run a typed-in command {FL_ALT+FL_F+3, Lower}, {FL_ALT+FL_F+4, Close}, // this matches KWM //{FL_ALT+FL_F+5, Restore}, // useless because no icons visible //{FL_ALT+FL_F+6, unknown}, // ? //{FL_ALT+FL_F+7, Move}, // grabs the window for movement //{FL_ALT+FL_F+8, Resize}, // grabs the window for resizing {FL_ALT+FL_F+9, Iconize}, //{FL_ALT+FL_F+10, Maximize}, //{FL_ALT+FL_F+11, unknown}, // ? {FL_ALT+FL_F+12, Close}, // actually does "quit" #else #if DESKTOPS && DESKTOP_HOTKEYS // seem to be common to Linux window managers {FL_ALT+FL_F+1, DeskNumber}, {FL_ALT+FL_F+2, DeskNumber}, {FL_ALT+FL_F+3, DeskNumber}, {FL_ALT+FL_F+4, DeskNumber}, {FL_ALT+FL_F+5, DeskNumber}, {FL_ALT+FL_F+6, DeskNumber}, {FL_ALT+FL_F+7, DeskNumber}, {FL_ALT+FL_F+8, DeskNumber}, {FL_ALT+FL_F+9, DeskNumber}, {FL_ALT+FL_F+10, DeskNumber}, {FL_ALT+FL_F+11, DeskNumber}, {FL_ALT+FL_F+12, DeskNumber}, #endif #endif {0}}; #if FL_MAJOR_VERSION > 1 // Define missing function, this should get put in fltk2.0: namespace fltk { int test_shortcut(int shortcut) { if (!shortcut) return 0; int shift = Fl::event_state(); // see if any required shift flags are off: if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0; // record shift flags that are wrong: int mismatch = (shortcut^shift)&0x7fff0000; // these three must always be correct: if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0; int key = shortcut & 0xffff; // if shift is also correct, check for exactly equal keysyms: if (!(mismatch&(FL_SHIFT)) && unsigned(key) == Fl::event_key()) return 1; // try matching ascii, ignore shift: if (key == event_text()[0]) return 1; // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'): if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F && event_text()[0]==(key^0x40)) return 1; return 0; } } #endif int Handle_Hotkey() { for (int i = 0; keybindings[i].key; i++) { if (Fl::test_shortcut(keybindings[i].key) || ((keybindings[i].key & 0xFFFF) == FL_Delete && Fl::event_key() == FL_BackSpace)// fltk bug? ) { keybindings[i].func(); return 1; } } return 0; } extern Fl_Window* Root; void Grab_Hotkeys() { XWindow root = fl_xid(Root); for (int i = 0; keybindings[i].key; i++) { int k = keybindings[i].key; int keycode = XKeysymToKeycode(fl_display, k & 0xFFFF); if (!keycode) continue; // Silly X! we need to ignore caps lock & numlock keys by grabbing // all the combinations: XGrabKey(fl_display, keycode, k>>16, root, 0, 1, 1); XGrabKey(fl_display, keycode, (k>>16)|2, root, 0, 1, 1); // CapsLock XGrabKey(fl_display, keycode, (k>>16)|16, root, 0, 1, 1); // NumLock XGrabKey(fl_display, keycode, (k>>16)|18, root, 0, 1, 1); // both } }