4 * Copyright (c) Tuomo Valkonen 1999-2008.
6 * See the included file LICENSE for details.
12 #include <libtu/util.h>
15 #include "fullscreen.h"
16 #include "clientwin.h"
27 static Atom atom_net_wm_name=0;
28 static Atom atom_net_wm_state=0;
29 static Atom atom_net_wm_state_fullscreen=0;
30 static Atom atom_net_supporting_wm_check=0;
31 static Atom atom_net_virtual_roots=0;
32 static Atom atom_net_active_window=0;
36 static Atom atom_net_supported=0;
41 /*{{{ Initialisation */
46 atom_net_wm_name=XInternAtom(ioncore_g.dpy, "_NET_WM_NAME", False);
47 atom_net_wm_state=XInternAtom(ioncore_g.dpy, "_NET_WM_STATE", False);
48 atom_net_wm_state_fullscreen=XInternAtom(ioncore_g.dpy, "_NET_WM_STATE_FULLSCREEN", False);
49 atom_net_supported=XInternAtom(ioncore_g.dpy, "_NET_SUPPORTED", False);
50 atom_net_supporting_wm_check=XInternAtom(ioncore_g.dpy, "_NET_SUPPORTING_WM_CHECK", False);
51 atom_net_virtual_roots=XInternAtom(ioncore_g.dpy, "_NET_VIRTUAL_ROOTS", False);
52 atom_net_active_window=XInternAtom(ioncore_g.dpy, "_NET_ACTIVE_WINDOW", False);
56 void netwm_init_rootwin(WRootWin *rw)
61 atoms[0]=atom_net_wm_name;
62 atoms[1]=atom_net_wm_state;
63 atoms[2]=atom_net_wm_state_fullscreen;
64 atoms[3]=atom_net_supporting_wm_check;
65 atoms[4]=atom_net_virtual_roots;
66 atoms[5]=atom_net_active_window;
68 XChangeProperty(ioncore_g.dpy, WROOTWIN_ROOT(rw),
69 atom_net_supporting_wm_check, XA_WINDOW,
70 32, PropModeReplace, (uchar*)&(rw->dummy_win), 1);
71 XChangeProperty(ioncore_g.dpy, WROOTWIN_ROOT(rw),
72 atom_net_supported, XA_ATOM,
73 32, PropModeReplace, (uchar*)atoms, N_NETWM);
75 p[0]=libtu_progbasename();
76 xwindow_set_text_property(rw->dummy_win, atom_net_wm_name, p, 1);
83 /*{{{ _NET_WM_STATE */
86 WScreen *netwm_check_initial_fullscreen(WClientWin *cwin)
93 n=xwindow_get_property(cwin->win, atom_net_wm_state, XA_ATOM,
94 1, TRUE, (uchar**)&data);
100 if(data[i]==(long)atom_net_wm_state_fullscreen)
101 return region_screen_of((WRegion*)cwin);
110 void netwm_update_state(WClientWin *cwin)
115 if(REGION_IS_FULLSCREEN(cwin))
116 data[n++]=atom_net_wm_state_fullscreen;
118 XChangeProperty(ioncore_g.dpy, cwin->win, atom_net_wm_state,
119 XA_ATOM, 32, PropModeReplace, (uchar*)data, n);
123 void netwm_delete_state(WClientWin *cwin)
125 XDeleteProperty(ioncore_g.dpy, cwin->win, atom_net_wm_state);
130 static void netwm_state_change_rq(WClientWin *cwin,
131 const XClientMessageEvent *ev)
133 if((ev->data.l[1]==0 ||
134 ev->data.l[1]!=(long)atom_net_wm_state_fullscreen) &&
136 ev->data.l[2]!=(long)atom_net_wm_state_fullscreen)){
140 /* Ok, full screen add/remove/toggle */
141 if(!REGION_IS_FULLSCREEN(cwin)){
142 if(ev->data.l[0]==_NET_WM_STATE_ADD ||
143 ev->data.l[0]==_NET_WM_STATE_TOGGLE){
144 WRegion *grp=region_groupleader_of((WRegion*)cwin);
145 bool sw=clientwin_fullscreen_may_switchto(cwin);
146 cwin->flags|=CLIENTWIN_FS_RQ;
147 if(!region_enter_fullscreen(grp, sw))
148 cwin->flags&=~CLIENTWIN_FS_RQ;
150 /* Should not be set.. */
151 cwin->flags&=~CLIENTWIN_FS_RQ;
154 if(ev->data.l[0]==_NET_WM_STATE_REMOVE ||
155 ev->data.l[0]==_NET_WM_STATE_TOGGLE){
156 WRegion *grp=region_groupleader_of((WRegion*)cwin);
157 bool sw=clientwin_fullscreen_may_switchto(cwin);
158 cwin->flags&=~CLIENTWIN_FS_RQ;
159 region_leave_fullscreen(grp, sw);
162 cwin->flags|=CLIENTWIN_FS_RQ;
171 /*{{{ _NET_ACTIVE_WINDOW */
174 void netwm_set_active(WRegion *reg)
176 CARD32 data[1]={None};
178 if(OBJ_IS(reg, WClientWin))
179 data[0]=region_xwindow(reg);
181 /* The spec doesn't say how multihead should be handled, so
182 * we just update the root window the window is on.
184 XChangeProperty(ioncore_g.dpy, region_root_of(reg),
185 atom_net_active_window, XA_WINDOW,
186 32, PropModeReplace, (uchar*)data, 1);
190 static void netwm_active_window_rq(WClientWin *cwin,
191 const XClientMessageEvent *ev)
195 extl_table_gets_b(cwin->proptab, "ignore_net_active_window", &ignore);
198 region_goto((WRegion*)cwin);
205 /*{{{ _NET_WM_NAME */
208 char **netwm_get_name(WClientWin *cwin)
210 return xwindow_get_text_property(cwin->win, atom_net_wm_name, NULL);
217 /*{{{ netwm_handle_client_message */
220 void netwm_handle_client_message(const XClientMessageEvent *ev)
222 /* Check _NET_WM_STATE fullscreen request */
223 if(ev->message_type==atom_net_wm_state && ev->format==32){
224 WClientWin *cwin=XWINDOW_REGION_OF_T(ev->window, WClientWin);
226 netwm_state_change_rq(cwin, ev);
228 /* Check _NET_ACTIVE_WINDOW request */
229 else if(ev->message_type==atom_net_active_window && ev->format==32){
230 WClientWin *cwin=XWINDOW_REGION_OF_T(ev->window, WClientWin);
232 netwm_active_window_rq(cwin, ev);
240 /*{{{ netwm_handle_property */
243 bool netwm_handle_property(WClientWin *cwin, const XPropertyEvent *ev)
245 if(ev->atom!=atom_net_wm_name)
248 clientwin_get_set_name(cwin);