// 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 <stdio.h>
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
}
}