summaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11AllowedWMActions.c
blob: 47448cba9452ec074207350297c87662e21e54bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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