diff options
author | Sven Gothel <[email protected]> | 2015-08-10 16:16:13 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-08-10 16:16:13 +0200 |
commit | 2d837a7a7130702ad36b694875613fae77c7ef06 (patch) | |
tree | f9027493d91511e9f799a852d3058d9fb29f9645 /src/newt/native/X11AllowedWMActions.c | |
parent | 1e4bfc26e2f220e046f42f7d26c05e4971bc509d (diff) |
Bug 1188, Bug 1186: NEWT Window: Support non-resizable, minimize, maximize, alwaysOnBottom and sticky/all-desktop (Part 1)
Change also implements Bug 1186: 'NEWT Window: Use a Bitfield holding all state flags and expose it accordingly',
since it is essential for an efficient implementation.
Part 1:
- Bug 1186
- Using Bitfield, holding public (Window) and private state bits/mask
- Bug 1188
- Window adds:
- [is|set]AlwaysOnBottom(..),
- [is|set]Resizable(..),
- [is|set]Sticky(..),
- [is|set]Maximized(..),
- isChildWindow(),
- Full implementation for X11
- TODO: Implement for OSX and Windows
- Manual tests:
- TestGearsES2NEWT, TestGearsES2NEWTSimple and TestGearsES2NewtCanvasAWT
utilize new NewtDemoListener, which has a key-listener to perform
all [new] actions. See source code of NewtDemoListener.
Diffstat (limited to 'src/newt/native/X11AllowedWMActions.c')
-rw-r--r-- | src/newt/native/X11AllowedWMActions.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/newt/native/X11AllowedWMActions.c b/src/newt/native/X11AllowedWMActions.c new file mode 100644 index 000000000..47448cba9 --- /dev/null +++ b/src/newt/native/X11AllowedWMActions.c @@ -0,0 +1,131 @@ + +#ifdef VERBOSE_ON + #define _NET_WM_ACTION_FLAG_RESERVED ( 1 << 0 ) /* for the ATOM COMMAND */ + #define _NET_WM_ACTION_FLAG_MOVE ( 1 << 1 ) + #define _NET_WM_ACTION_FLAG_RESIZE ( 1 << 2 ) + #define _NET_WM_ACTION_FLAG_MINIMIZE ( 1 << 3 ) + #define _NET_WM_ACTION_FLAG_SHADE ( 1 << 4 ) + #define _NET_WM_ACTION_FLAG_STICK ( 1 << 5 ) + #define _NET_WM_ACTION_FLAG_MAXIMIZE_HORZ ( 1 << 6 ) + #define _NET_WM_ACTION_FLAG_MAXIMIZE_VERT ( 1 << 7 ) + #define _NET_WM_ACTION_FLAG_FULLSCREEN ( 1 << 8 ) + #define _NET_WM_ACTION_FLAG_CHANGE_DESKTOP ( 1 << 9 ) + #define _NET_WM_ACTION_FLAG_CLOSE ( 1 << 10 ) + #define _NET_WM_ACTION_FLAG_ABOVE ( 1 << 11 ) + #define _NET_WM_ACTION_FLAG_BELOW ( 1 << 12 ) + #define _NET_WM_ACTION_FLAG_ALL ( ( 1 << 13 ) - 1 ) + static const char * _NET_WM_AACTION_NAMES[] = { + "_NET_WM_ALLOWED_ACTIONS", + "_NET_WM_ACTION_MOVE", + "_NET_WM_ACTION_RESIZE", + "_NET_WM_ACTION_MINIMIZE", + "_NET_WM_ACTION_SHADE", + "_NET_WM_ACTION_STICK", + "_NET_WM_ACTION_MAXIMIZE_HORZ", + "_NET_WM_ACTION_MAXIMIZE_VERT", + "_NET_WM_ACTION_FULLSCREEN", + "_NET_WM_ACTION_CHANGE_DESKTOP", + "_NET_WM_ACTION_CLOSE", + "_NET_WM_ACTION_ABOVE", + "_NET_WM_ACTION_BELOW" + }; + static const int _NET_WM_AACTION_COUNT = sizeof(_NET_WM_AACTION_NAMES)/sizeof(const char *); + static const int _UNDEF_AACTION_MAX = 16; + static int NewtWindows_getAllowedWindowActionEWMH(Display *dpy, const Atom * allDefinedActions, const Atom action, const int num) { + int i; + for(i=1; i<_NET_WM_AACTION_COUNT; i++) { + if( action == allDefinedActions[i] ) { + DBG_PRINT( "...... [%d] -> [%d/%d]: %s\n", num, i, _NET_WM_AACTION_COUNT, _NET_WM_AACTION_NAMES[i]); + return 1 << i; + } + } + #ifdef VERBOSE_ON + char * astr = XGetAtomName(dpy, action); + DBG_PRINT( "...... [%d] -> [_/%d]: %s (undef)\n", num, _NET_WM_AACTION_COUNT, astr); + XFree(astr); + #endif + return 0; + } + static int NewtWindows_getAllowedWindowActionsEWMH1(Display *dpy, Window w, Atom * _NET_WM_AACTIONS) { + Atom * actions = NULL; + Atom type = 0; + unsigned long action_len = 0, remain = 0; + int res = 0, form = 0, i = 0; + Status s; + + XSync(dpy, False); + DBG_PRINT( "**************** X11: AACTIONS EWMH CHECK for Window: %p:\n", w); + if ( Success == (s = XGetWindowProperty(dpy, w, _NET_WM_AACTIONS[0], 0, 1024, False, AnyPropertyType, + &type, &form, &action_len, &remain, (unsigned char**)&actions)) ) { + if( NULL != actions ) { + for(i=0; i<action_len; i++) { + res |= NewtWindows_getAllowedWindowActionEWMH(dpy, _NET_WM_AACTIONS, actions[i], i); + } + XFree(actions); + } + DBG_PRINT( "**************** X11: AACTIONS EWMH CHECK: 0x%X\n", res); + } else { + DBG_PRINT( "**************** X11: AACTIONS EWMH CHECK: XGetWindowProperty failed: %d\n", s); + res = _NET_WM_ACTION_FLAG_FULLSCREEN; // default .. + } + return res; + } + static int NewtWindows_getAllowedWindowActionsEWMH0(Display *dpy, Window w) { + Atom _NET_WM_AACTIONS[_NET_WM_AACTION_COUNT]; + if( 0 == XInternAtoms( dpy, (char **)_NET_WM_AACTION_NAMES, _NET_WM_AACTION_COUNT, False, _NET_WM_AACTIONS) ) { + // error + DBG_PRINT( "**************** X11: AACTIONS EWMH CHECK: XInternAtoms failed\n"); + return _NET_WM_ACTION_FLAG_FULLSCREEN; // default .. + } + return NewtWindows_getAllowedWindowActionsEWMH1(dpy, w, _NET_WM_AACTIONS); + } + static int NewtWindows_setAllowedWindowActionsEWMH(Display *dpy, Window w, int new_action_mask) { + Atom _NET_WM_AACTIONS[_NET_WM_AACTION_COUNT]; + if( 0 == XInternAtoms( dpy, (char **)_NET_WM_AACTION_NAMES, _NET_WM_AACTION_COUNT, False, _NET_WM_AACTIONS) ) { + // error + DBG_PRINT( "**************** X11: AACTIONS EWMH SET: XInternAtoms failed\n"); + return _NET_WM_ACTION_FLAG_FULLSCREEN; // default .. + } + Atom * actions = NULL; + Atom type = 0; + unsigned long action_len = 0, remain = 0; + int res = 0, form = 0, i = 0, j = 0; + Status s; + Atom _NET_WM_NEWACTIONS[_NET_WM_AACTION_COUNT+_UNDEF_AACTION_MAX]; // +_UNDEF_AACTION_MAX undefined props + + DBG_PRINT( "**************** X11: AACTIONS EWMH SET for Window: %p:\n", w); + if ( Success == (s = XGetWindowProperty(dpy, w, _NET_WM_AACTIONS[0], 0, 1024, False, AnyPropertyType, + &type, &form, &action_len, &remain, (unsigned char**)&actions)) ) { + if( NULL != actions ) { + for(i=0; i<action_len; i++) { + const int r = NewtWindows_getAllowedWindowActionEWMH(dpy, _NET_WM_AACTIONS, actions[i], i); + if( 0 == r && j < _UNDEF_AACTION_MAX ) { + // conserve undefined action + _NET_WM_NEWACTIONS[j++] = actions[i]; + } + res |= r; + } + XFree(actions); + } + DBG_PRINT( "**************** X11: AACTIONS EWMH SET: Has 0x%X\n", res); + for(i=1; i<_NET_WM_AACTION_COUNT; i++) { + const int m = 1 << i; + if( 0 != ( m & new_action_mask ) ) { + // requested + _NET_WM_NEWACTIONS[j++] = _NET_WM_AACTIONS[i]; + res |= m; + } + } + DBG_PRINT( "**************** X11: AACTIONS EWMH SET: New 0x%X\n", res); + XChangeProperty( dpy, w, _NET_WM_AACTIONS[0], XA_ATOM, 32, PropModeReplace, (unsigned char*)_NET_WM_NEWACTIONS, j); + XSync(dpy, False); + const int res2 = NewtWindows_getAllowedWindowActionsEWMH1(dpy, w, _NET_WM_AACTIONS); + DBG_PRINT( "**************** X11: AACTIONS EWMH SET: Val 0x%X\n", res2); + } else { + DBG_PRINT( "**************** X11: AACTIONS EWMH SET: XGetWindowProperty failed: %d\n", s); + res = _NET_WM_ACTION_FLAG_FULLSCREEN; // default .. + } + return res; + } +#endif + |