mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-24 14:22:40 -06:00
CtrlCore: GTK/X11 RegisterSystemHotKey #379
git-svn-id: svn://ultimatepp.org/upp/trunk@5724 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
fb80a72de4
commit
d676e2d8ec
5 changed files with 108 additions and 23 deletions
|
|
@ -30,6 +30,7 @@ void InitGtkApp(int argc, char **argv, const char **envptr)
|
|||
Ctrl::ReSkin();
|
||||
g_timeout_add(20, (GSourceFunc) Ctrl::TimeHandler, NULL);
|
||||
InstallPanicMessageBox(Ctrl::PanicMsgBox);
|
||||
gdk_window_add_filter(NULL, Ctrl::RootKeyFilter, NULL);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -156,7 +156,11 @@ public: // really private:
|
|||
static Gclipboard& gclipboard();
|
||||
static Gclipboard& gselection();
|
||||
static String RenderPrimarySelection(const Value& fmt);
|
||||
|
||||
|
||||
static Vector<Callback> hotkey;
|
||||
static Vector<dword> keyhot;
|
||||
static Vector<dword> modhot;
|
||||
|
||||
public:
|
||||
static void EndSession() {}
|
||||
static bool IsEndSession() { return false; }
|
||||
|
|
@ -169,4 +173,7 @@ public:
|
|||
|
||||
GdkWindow *gdk() const { return top ? top->window->window : NULL; }
|
||||
GtkWindow *gtk() const { return top ? (GtkWindow *)top->window : NULL; }
|
||||
|
||||
static GdkFilterReturn RootKeyFilter(GdkXEvent *xevent, GdkEvent *event, gpointer data);
|
||||
|
||||
//$ };
|
||||
|
|
|
|||
|
|
@ -446,7 +446,20 @@ void Ctrl::Proc()
|
|||
kv |= K_CTRL;
|
||||
if(GetAlt() && kv != K_ALT_KEY)
|
||||
kv |= K_ALT;
|
||||
LLOG(GetKeyDesc(kv) << ", pressed: " << pressed << ", count: " << CurrentEvent.count);
|
||||
DLOG(GetKeyDesc(kv) << ", pressed: " << pressed << ", count: " << CurrentEvent.count);
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
DDUMP(FormatIntHex(kv));
|
||||
if(pressed)
|
||||
for(int i = 0; i < hotkey.GetCount(); i++) {
|
||||
DDUMP(FormatIntHex(keyhot[i]));
|
||||
DDUMP((bool)hotkey[i]);
|
||||
if(hotkey[i] && keyhot[i] == kv) {
|
||||
DLOG("CALL!");
|
||||
hotkey[i]();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
DispatchKey(!pressed * K_KEYUP + kv, CurrentEvent.count);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ NAMESPACE_UPP
|
|||
|
||||
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
|
||||
|
||||
Vector<Callback> Ctrl::hotkey;
|
||||
Vector<dword> Ctrl::keyhot;
|
||||
Vector<dword> Ctrl::modhot;
|
||||
|
||||
Vector<Ctrl::Win> Ctrl::wins;
|
||||
|
||||
int Ctrl::WndCaretTime;
|
||||
|
|
@ -110,36 +114,21 @@ Ctrl *Ctrl::GetActiveCtrl()
|
|||
|
||||
// Vector<Callback> Ctrl::hotkey;
|
||||
|
||||
#ifndef GDK_WINDOWING_X11
|
||||
|
||||
// There is no generic support in GTK for HotKey
|
||||
|
||||
int Ctrl::RegisterSystemHotKey(dword key, Callback cb)
|
||||
{
|
||||
/* ASSERT(key >= K_DELTA);
|
||||
int q = hotkey.GetCount();
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(!hotkey[i]) {
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
hotkey.At(q) = cb;
|
||||
dword mod = 0;
|
||||
if(key & K_ALT)
|
||||
mod |= MOD_ALT;
|
||||
if(key & K_SHIFT)
|
||||
mod |= MOD_SHIFT;
|
||||
if(key & K_CTRL)
|
||||
mod |= MOD_CONTROL;
|
||||
|
||||
return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::UnregisterSystemHotKey(int id)
|
||||
{
|
||||
/* if(id >= 0 && id < hotkey.GetCount()) {
|
||||
UnregisterHotKey(NULL, id);
|
||||
hotkey[id].Clear();
|
||||
}*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Ctrl::AnimateCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ XDisplay *Xdisplay()
|
|||
return GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
|
||||
}
|
||||
|
||||
Window Xroot()
|
||||
{
|
||||
return GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(gdk_screen_get_default()));
|
||||
}
|
||||
|
||||
String GetProperty(Window w, Atom property, Atom rtype)
|
||||
{
|
||||
GuiLock __;
|
||||
|
|
@ -88,6 +93,76 @@ Vector<int> GetPropertyInts(GdkWindow *w, const char *property)
|
|||
return result;
|
||||
}
|
||||
|
||||
dword X11mods(dword key)
|
||||
{
|
||||
dword mod = 0;
|
||||
if(key & K_ALT)
|
||||
mod |= Mod1Mask;
|
||||
if(key & K_SHIFT)
|
||||
mod |= ShiftMask;
|
||||
if(key & K_CTRL)
|
||||
mod |= ControlMask;
|
||||
return mod;
|
||||
}
|
||||
|
||||
int Ctrl::RegisterSystemHotKey(dword key, Callback cb)
|
||||
{
|
||||
GuiLock __;
|
||||
DDUMP(FormatIntHex(key));
|
||||
ASSERT(key >= K_DELTA);
|
||||
gdk_error_trap_push();
|
||||
KeyCode k = XKeysymToKeycode(Xdisplay(), key & 0xffff);
|
||||
dword mod = X11mods(key);
|
||||
bool r = false;
|
||||
for(dword nlock = 0; nlock < 2; nlock++)
|
||||
for(dword clock = 0; clock < 2; clock++)
|
||||
for(dword slock = 0; slock < 2; slock++)
|
||||
r = XGrabKey(Xdisplay(), k,
|
||||
mod | (nlock * Mod2Mask) | (clock * LockMask) | (slock * Mod3Mask),
|
||||
Xroot(), true, GrabModeAsync, GrabModeAsync) || r;
|
||||
gdk_error_trap_pop();
|
||||
if(!r) return -1;
|
||||
int q = hotkey.GetCount();
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(!hotkey[i]) {
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
hotkey.At(q) = cb;
|
||||
keyhot.At(q) = k;
|
||||
modhot.At(q) = mod;
|
||||
return q;
|
||||
}
|
||||
|
||||
void Ctrl::UnregisterSystemHotKey(int id)
|
||||
{
|
||||
GuiLock __;
|
||||
if(id >= 0 && id < hotkey.GetCount() && hotkey[id]) {
|
||||
gdk_error_trap_push();
|
||||
for(dword nlock = 0; nlock < 2; nlock++)
|
||||
for(dword clock = 0; clock < 2; clock++)
|
||||
for(dword slock = 0; slock < 2; slock++)
|
||||
XUngrabKey(Xdisplay(), keyhot[id],
|
||||
modhot[id] | (nlock * Mod2Mask) | (clock * LockMask) | (slock * Mod3Mask),
|
||||
Xroot());
|
||||
gdk_error_trap_pop();
|
||||
hotkey[id].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
GdkFilterReturn Ctrl::RootKeyFilter(GdkXEvent *xevent, GdkEvent *Xevent, gpointer data)
|
||||
{
|
||||
XEvent *event = (XEvent *)xevent;
|
||||
if(event->type == KeyPress)
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(hotkey[i] && keyhot[i] == event->xkey.keycode &&
|
||||
modhot[i] == (event->xkey.state & (Mod1Mask|ShiftMask|ControlMask))) {
|
||||
hotkey[i]();
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue