1 /* kwm.c-- stuff for support for kwm hints
3 * Window Maker window manager
5 * Copyright (c) 1998, 1999 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 * kfm icon selection from krootbgwm
30 * kwm.h function/method Notes
31 *----------------------------------------------------------------------------
32 * setUnsavedDataHint() currently, only gives visual clue that
33 * there is unsaved data (broken X close button)
35 * setIcon() std X thing...
39 * setWmCommand() std X thing
43 * isKWMInitialized() not trustworthy
44 * activeWindow() dunno it's use, but since it's easy to
45 * implement it won't hurt to support
47 * (set/get)WindowRegion()
48 * (set)numberOfDesktops() KDE limits to 32, but wmaker is virtually
49 * unlimited. May raise some incompatibility
50 * in badly written KDE modules?
51 * (set/get)DesktopName()
52 * sendKWMCommand() also does the message relay thing
58 * moveToDesktop() WARNING: evil mechanism
59 * setGeometryRestore() WARNING: evil mechanism
60 * setMaximize() woo hoo! wanna race?
61 * setIconify() BAH!: why reinvent the f'ing wheel!?
64 * setGeometry() std X thing
70 * prepareForSwallowing() std X thing
71 * doNotManage() klugy thing...
72 * getBlablablaString()
73 * setKWMDockModule() maybe we can make the Dock behave as the KDE
74 * dock, but must figure where to show the windows
77 * Unsupported stuff (superfluous/not-essential/nonsense):
78 * =======================================================
84 * registerSoundEvent()
85 * unregisterSoundEvent()
88 * geometry() kde lib code makes it unnecessary
94 * These are clientmessage-type messages specific to Window Maker:
95 * wmaker:info - show info panel
96 * wmaker:legal - show legal panel
97 * wmaker:arrangeIcons - arrange icons
98 * wmaker:showAll - show all windows
99 * wmaker:hideOthers - hide others
100 * wmaker:restart - restart wmaker
101 * wmaker:exit - exit wmaker
106 * different WORKAREA for each workspace
114 #include <X11/Xlib.h>
115 #include <X11/Xutil.h>
116 #include <X11/Xatom.h>
123 #include <sys/types.h>
124 #include <sys/socket.h>
129 #include "WindowMaker.h"
133 #include "framewin.h"
135 #include "properties.h"
140 #include "workspace.h"
142 #include "stacking.h"
148 /******* Global ******/
150 extern Time LastFocusChange
;
151 extern Time LastTimestamp
;
154 extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW
;
155 extern Atom _XA_WM_DELETE_WINDOW
;
159 static Atom _XA_KWM_COMMAND
= 0;
160 static Atom _XA_KWM_ACTIVATE_WINDOW
= 0;
161 static Atom _XA_KWM_ACTIVE_WINDOW
= 0;
162 static Atom _XA_KWM_DO_NOT_MANAGE
= 0;
163 static Atom _XA_KWM_DOCKWINDOW
= 0;
164 static Atom _XA_KWM_RUNNING
= 0;
166 static Atom _XA_KWM_MODULE
= 0;
168 static Atom _XA_KWM_MODULE_INIT
= 0;
169 static Atom _XA_KWM_MODULE_INITIALIZED
= 0;
170 static Atom _XA_KWM_MODULE_DESKTOP_CHANGE
= 0;
171 static Atom _XA_KWM_MODULE_DESKTOP_NAME_CHANGE
= 0;
172 static Atom _XA_KWM_MODULE_DESKTOP_NUMBER_CHANGE
= 0;
173 static Atom _XA_KWM_MODULE_WIN_ADD
= 0;
174 static Atom _XA_KWM_MODULE_WIN_REMOVE
= 0;
175 static Atom _XA_KWM_MODULE_WIN_CHANGE
= 0;
176 static Atom _XA_KWM_MODULE_WIN_RAISE
= 0;
177 static Atom _XA_KWM_MODULE_WIN_LOWER
= 0;
178 static Atom _XA_KWM_MODULE_WIN_ACTIVATE
= 0;
179 static Atom _XA_KWM_MODULE_WIN_ICON_CHANGE
= 0;
180 static Atom _XA_KWM_MODULE_DOCKWIN_ADD
= 0;
181 static Atom _XA_KWM_MODULE_DOCKWIN_REMOVE
= 0;
183 static Atom _XA_KWM_WIN_UNSAVED_DATA
= 0;
184 static Atom _XA_KWM_WIN_DECORATION
= 0;
185 static Atom _XA_KWM_WIN_DESKTOP
= 0;
186 static Atom _XA_KWM_WIN_GEOMETRY_RESTORE
= 0;
187 static Atom _XA_KWM_WIN_ICONIFIED
= 0;
188 static Atom _XA_KWM_WIN_MAXIMIZED
= 0;
189 static Atom _XA_KWM_WIN_STICKY
= 0;
191 static Atom _XA_KWM_WIN_ICON_GEOMETRY
= 0;
193 static Atom _XA_KWM_CURRENT_DESKTOP
= 0;
194 static Atom _XA_KWM_NUMBER_OF_DESKTOPS
= 0;
195 static Atom _XA_KWM_DESKTOP_NAME_
[MAX_WORKSPACES
];
196 static Atom _XA_KWM_WINDOW_REGION_
[MAX_WORKSPACES
];
200 /* list of window titles that must not be managed */
201 typedef struct KWMDoNotManageList
{
203 struct KWMDoNotManageList
*next
;
204 } KWMDoNotManageList
;
206 static KWMDoNotManageList
*KWMDoNotManageCrap
= NULL
;
209 /* list of KWM modules */
210 typedef struct KWMModuleList
{
212 struct KWMModuleList
*next
;
218 static KWMModuleList
*KWMModules
= NULL
;
220 static KWMModuleList
*KWMDockWindows
= NULL
;
222 /* window decoration types */
225 KWMnormalDecoration
= 1,
226 KWMtinyDecoration
= 2,
228 KWMstandaloneMenuBar
= 512,
229 KWMdesktopIcon
= 1024,
236 getSimpleHint(Window win
, Atom atom
, long *retval
)
242 data
= (long*)PropGetCheckProperty(win
, atom
, atom
, 32, 1, NULL
);
257 setSimpleHint(Window win
, Atom atom
, long value
)
260 XChangeProperty(dpy
, win
, atom
, atom
,
261 32, PropModeReplace
, (unsigned char*)&value
, 1);
266 sendClientMessage(WScreen
*scr
, Window window
, Atom atom
, long value
)
273 memset(&event
, 0, sizeof(XEvent
));
274 event
.xclient
.type
= ClientMessage
;
275 event
.xclient
.message_type
= atom
;
276 event
.xclient
.window
= window
;
277 event
.xclient
.format
= 32;
278 event
.xclient
.data
.l
[0] = value
;
279 event
.xclient
.data
.l
[1] = LastTimestamp
;
281 if (scr
&& scr
->root_win
== window
)
282 mask
= SubstructureRedirectMask
;
284 XSendEvent(dpy
, window
, False
, mask
, &event
);
289 sendTextMessage(WScreen
*scr
, Window window
, Atom atom
, char *text
)
297 memset(&event
, 0, sizeof(XEvent
));
298 event
.xclient
.type
= ClientMessage
;
299 event
.xclient
.message_type
= atom
;
300 event
.xclient
.window
= window
;
301 event
.xclient
.format
= 8;
303 for (i
=0; i
<20 && text
[i
]; i
++)
304 event
.xclient
.data
.b
[i
] = text
[i
];
306 if (scr
&& scr
->root_win
== window
)
307 mask
= SubstructureRedirectMask
;
309 XSendEvent(dpy
, window
, False
, mask
, &event
);
314 getAreaHint(Window win
, Atom atom
, WArea
*area
)
318 data
= (long*)PropGetCheckProperty(win
, atom
, atom
, 32, 4, NULL
);
325 area
->x2
= data
[2] + area
->x1
;
326 area
->y2
= data
[3] + area
->y1
;
335 setAreaHint(Window win
, Atom atom
, WArea area
)
342 value
[2] = area
.x2
- area
.x1
;
343 value
[3] = area
.y2
- area
.y1
;
344 XChangeProperty(dpy
, win
, atom
, atom
, 32, PropModeReplace
,
345 (unsigned char*)&value
, 4);
350 addModule(WScreen
*scr
, Window window
)
356 node
= malloc(sizeof(KWMModuleList
));
358 wwarning("out of memory while registering KDE module");
362 node
->next
= KWMModules
;
363 node
->window
= window
;
366 sendClientMessage(scr
, window
, _XA_KWM_MODULE_INIT
, 0);
368 if (getSimpleHint(window
, _XA_KWM_MODULE
, &val
) && val
==2) {
369 if (scr
->kwm_dock
!= None
) {
370 setSimpleHint(window
, _XA_KWM_MODULE
, 1);
374 scr
->kwm_dock
= window
;
376 for (ptr
= KWMDockWindows
; ptr
!=NULL
; ptr
= ptr
->next
) {
377 sendClientMessage(scr
, scr
->kwm_dock
, _XA_KWM_MODULE_DOCKWIN_ADD
,
383 /* send list of windows */
384 for (ptr
= scr
->focused_window
; ptr
!=NULL
; ptr
= ptr
->prev
) {
385 if (!ptr
->flags
.kwm_hidden_for_modules
386 && !WFLAGP(ptr
, skip_window_list
)) {
387 sendClientMessage(scr
, window
, _XA_KWM_MODULE_WIN_ADD
,
392 /* send window stacking order */
393 wKWMSendStacking(scr
, window
);
395 /* send focused window */
396 if (scr
->focused_window
&& scr
->focused_window
->flags
.focused
) {
397 sendClientMessage(scr
, window
, _XA_KWM_MODULE_WIN_ACTIVATE
,
398 scr
->focused_window
->client_win
);
401 /* tell who we are */
402 sendTextMessage(scr
, window
, _XA_KWM_COMMAND
, "wm:wmaker");
405 sendClientMessage(scr
, window
, _XA_KWM_MODULE_INITIALIZED
, 0);
407 KWMModules
->title
= NULL
;
408 XFetchName(dpy
, window
, &KWMModules
->title
);
409 printf("NEW MODULE %s\n", KWMModules
->title
);
415 removeModule(WScreen
*scr
, Window window
)
423 if (KWMModules
->window
== window
) {
424 next
= KWMModules
->next
;
426 printf("REMOVING MODULE %s\n", KWMModules
->title
);
427 if (KWMModules
->title
)
428 XFree(KWMModules
->title
);
437 if (ptr
->next
->window
== window
) {
438 next
= ptr
->next
->next
;
440 printf("REMOVING MODULE %s\n", ptr
->next
->title
);
441 if (ptr
->next
->title
)
442 XFree(ptr
->next
->title
);
445 ptr
->next
->next
= next
;
448 ptr
->next
= ptr
->next
->next
;
452 if (scr
->kwm_dock
== window
)
453 scr
->kwm_dock
= None
;
459 addDockWindow(WScreen
*scr
, Window window
)
463 for (ptr
= KWMDockWindows
; ptr
!= NULL
; ptr
= ptr
->next
) {
464 if (ptr
->window
== window
)
470 node
= malloc(sizeof(KWMModuleList
));
472 wwarning("out of memory while processing KDE dock window");
475 node
->next
= KWMDockWindows
;
476 KWMDockWindows
= node
;
477 node
->window
= window
;
478 XSelectInput(dpy
, window
, StructureNotifyMask
);
480 sendClientMessage(scr
, scr
->kwm_dock
, _XA_KWM_MODULE_DOCKWIN_ADD
,
487 removeDockWindow(WScreen
*scr
, Window window
)
492 if (KWMDockWindows
->window
== window
) {
495 sendClientMessage(scr
, scr
->kwm_dock
, _XA_KWM_MODULE_DOCKWIN_REMOVE
,
498 next
= KWMDockWindows
->next
;
499 wfree(KWMDockWindows
);
500 KWMDockWindows
= next
;
503 KWMModuleList
*ptr
, *next
;
505 ptr
= KWMDockWindows
;
507 if (ptr
->next
->window
== window
) {
508 sendClientMessage(scr
, scr
->kwm_dock
,
509 _XA_KWM_MODULE_DOCKWIN_REMOVE
, window
);
510 next
= ptr
->next
->next
;
522 sendToModules(WScreen
*scr
, Atom atom
, WWindow
*wwin
, long data
)
529 if (wwin
->flags
.kwm_hidden_for_modules
530 || WFLAGP(wwin
, skip_window_list
))
532 data
= wwin
->client_win
;
535 printf("notifying %s\n",XGetAtomName(dpy
, atom
));
537 memset(&event
, 0, sizeof(XEvent
));
538 event
.xclient
.type
= ClientMessage
;
539 event
.xclient
.message_type
= atom
;
540 event
.xclient
.format
= 32;
541 event
.xclient
.data
.l
[1] = LastTimestamp
;
544 if (scr
&& scr
->root_win
== data
)
545 mask
= SubstructureRedirectMask
;
547 for (ptr
= KWMModules
; ptr
!=NULL
; ptr
= ptr
->next
) {
548 event
.xclient
.window
= ptr
->window
;
549 event
.xclient
.data
.l
[0] = data
;
550 XSendEvent(dpy
, ptr
->window
, False
, mask
, &event
);
556 wKWMInitStuff(WScreen
*scr
)
558 if (!_XA_KWM_WIN_STICKY
) {
559 _XA_KWM_WIN_UNSAVED_DATA
= XInternAtom(dpy
, "KWM_WIN_UNSAVED_DATA",
562 _XA_KWM_WIN_DECORATION
= XInternAtom(dpy
, "KWM_WIN_DECORATION", False
);
564 _XA_KWM_WIN_DESKTOP
= XInternAtom(dpy
, "KWM_WIN_DESKTOP", False
);
566 _XA_KWM_WIN_GEOMETRY_RESTORE
= XInternAtom(dpy
,
567 "KWM_WIN_GEOMETRY_RESTORE",
570 _XA_KWM_WIN_STICKY
= XInternAtom(dpy
, "KWM_WIN_STICKY", False
);
572 _XA_KWM_WIN_ICONIFIED
= XInternAtom(dpy
, "KWM_WIN_ICONIFIED", False
);
574 _XA_KWM_WIN_MAXIMIZED
= XInternAtom(dpy
, "KWM_WIN_MAXIMIZED", False
);
576 _XA_KWM_WIN_ICON_GEOMETRY
= XInternAtom(dpy
, "KWM_WIN_ICON_GEOMETRY",
579 _XA_KWM_COMMAND
= XInternAtom(dpy
, "KWM_COMMAND", False
);
581 _XA_KWM_ACTIVE_WINDOW
= XInternAtom(dpy
, "KWM_ACTIVE_WINDOW", False
);
583 _XA_KWM_ACTIVATE_WINDOW
= XInternAtom(dpy
, "KWM_ACTIVATE_WINDOW",
586 _XA_KWM_DO_NOT_MANAGE
= XInternAtom(dpy
, "KWM_DO_NOT_MANAGE", False
);
588 _XA_KWM_CURRENT_DESKTOP
= XInternAtom(dpy
, "KWM_CURRENT_DESKTOP",
591 _XA_KWM_NUMBER_OF_DESKTOPS
= XInternAtom(dpy
, "KWM_NUMBER_OF_DESKTOPS",
594 _XA_KWM_DOCKWINDOW
= XInternAtom(dpy
, "KWM_DOCKWINDOW", False
);
596 _XA_KWM_RUNNING
= XInternAtom(dpy
, "KWM_RUNNING", False
);
598 _XA_KWM_MODULE
= XInternAtom(dpy
, "KWM_MODULE", False
);
600 _XA_KWM_MODULE_INIT
= XInternAtom(dpy
, "KWM_MODULE_INIT", False
);
601 _XA_KWM_MODULE_INITIALIZED
= XInternAtom(dpy
, "KWM_MODULE_INITIALIZED", False
);
603 /* dunno what these do, but Matthias' patch contains it... */
604 _XA_KWM_MODULE_DESKTOP_CHANGE
= XInternAtom(dpy
, "KWM_MODULE_DESKTOP_CHANGE", False
);
605 _XA_KWM_MODULE_DESKTOP_NAME_CHANGE
= XInternAtom(dpy
, "KWM_MODULE_DESKTOP_NAME_CHANGE", False
);
606 _XA_KWM_MODULE_DESKTOP_NUMBER_CHANGE
= XInternAtom(dpy
, "KWM_MODULE_DESKTOP_NUMBER_CHANGE", False
);
608 _XA_KWM_MODULE_WIN_ADD
= XInternAtom(dpy
, "KWM_MODULE_WIN_ADD", False
);
609 _XA_KWM_MODULE_WIN_REMOVE
= XInternAtom(dpy
, "KWM_MODULE_WIN_REMOVE", False
);
610 _XA_KWM_MODULE_WIN_CHANGE
= XInternAtom(dpy
, "KWM_MODULE_WIN_CHANGE", False
);
611 _XA_KWM_MODULE_WIN_RAISE
= XInternAtom(dpy
, "KWM_MODULE_WIN_RAISE", False
);
612 _XA_KWM_MODULE_WIN_LOWER
= XInternAtom(dpy
, "KWM_MODULE_WIN_LOWER", False
);
613 _XA_KWM_MODULE_WIN_ACTIVATE
= XInternAtom(dpy
, "KWM_MODULE_WIN_ACTIVATE", False
);
614 _XA_KWM_MODULE_WIN_ICON_CHANGE
= XInternAtom(dpy
, "KWM_MODULE_WIN_ICON_CHANGE", False
);
615 _XA_KWM_MODULE_DOCKWIN_ADD
= XInternAtom(dpy
, "KWM_MODULE_DOCKWIN_ADD", False
);
616 _XA_KWM_MODULE_DOCKWIN_REMOVE
= XInternAtom(dpy
, "KWM_MODULE_DOCKWIN_REMOVE", False
);
618 memset(_XA_KWM_WINDOW_REGION_
, 0, sizeof(_XA_KWM_WINDOW_REGION_
));
620 memset(_XA_KWM_DESKTOP_NAME_
, 0, sizeof(_XA_KWM_DESKTOP_NAME_
));
623 #define SETSTR(hint, str) {\
624 static Atom a = 0; if (!a) a = XInternAtom(dpy, #hint, False);\
625 XChangeProperty(dpy, scr->root_win, a, XA_STRING, 8, PropModeReplace,\
626 (unsigned char*)str, strlen(str));}
628 SETSTR(KWM_STRING_MAXIMIZE
, _("Maximize"));
629 SETSTR(KWM_STRING_UNMAXIMIZE
, _("Unmaximize"));
630 SETSTR(KWM_STRING_ICONIFY
, _("Miniaturize"));
631 SETSTR(KWM_STRING_UNICONIFY
, _("Deminiaturize"));
632 SETSTR(KWM_STRING_STICKY
, _("Omnipresent"));
633 SETSTR(KWM_STRING_UNSTICKY
, _("Not Omnipresent"));
634 SETSTR(KWM_STRING_STRING_MOVE
, _("Move"));
635 SETSTR(KWM_STRING_STRING_RESIZE
, _("Resize"));
636 SETSTR(KWM_STRING_CLOSE
, _("Close"));
637 SETSTR(KWM_STRING_TODESKTOP
, _("Move To"));
638 SETSTR(KWM_STRING_ONTOCURRENTDESKTOP
, _("Bring Here"));
644 wKWMSendStacking(WScreen
*scr
, Window module
)
649 WM_ITERATE_BAG(scr
->stacking_list
, core
, i
) {
650 for (; core
!= NULL
; core
= core
->stacking
->under
) {
653 wwin
= wWindowFor(core
->window
);
655 sendClientMessage(scr
, module
, _XA_KWM_MODULE_WIN_RAISE
,
663 wKWMBroadcastStacking(WScreen
*scr
)
665 KWMModuleList
*ptr
= KWMModules
;
668 wKWMSendStacking(scr
, ptr
->window
);
676 wKWMGetWorkspaceName(WScreen
*scr
, int workspace
)
680 unsigned long nitems_ret
;
681 unsigned long bytes_after_ret
;
682 char *data
= NULL
, *tmp
;
685 assert(workspace
>= 0 && workspace
< MAX_WORKSPACES
);
687 if (_XA_KWM_DESKTOP_NAME_
[workspace
]==0) {
688 sprintf(buffer
, "KWM_DESKTOP_NAME_%d", workspace
+ 1);
690 _XA_KWM_DESKTOP_NAME_
[workspace
] = XInternAtom(dpy
, buffer
, False
);
693 /* What do these people have against correctly using property types? */
694 if (XGetWindowProperty(dpy
, scr
->root_win
,
695 _XA_KWM_DESKTOP_NAME_
[workspace
], 0, 128, False
,
697 &type_ret
, &fmt_ret
, &nitems_ret
, &bytes_after_ret
,
698 (unsigned char**)&data
)!=Success
|| !data
)
709 wKWMSetInitializedHint(WScreen
*scr
)
711 setSimpleHint(scr
->root_win
, _XA_KWM_RUNNING
, 1);
716 wKWMShutdown(WScreen
*scr
, Bool closeModules
)
720 XDeleteProperty(dpy
, scr
->root_win
, _XA_KWM_RUNNING
);
723 for (ptr
= KWMModules
; ptr
!= NULL
; ptr
= ptr
->next
) {
724 XKillClient(dpy
, ptr
->window
);
731 wKWMCheckClientHints(WWindow
*wwin
, int *layer
, int *workspace
)
735 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_UNSAVED_DATA
, &val
)
738 wwin
->client_flags
.broken_close
= 1;
740 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_DECORATION
, &val
)) {
741 if (val
& KWMnoFocus
) {
742 wwin
->client_flags
.no_focusable
= 1;
744 switch (val
& ~KWMnoFocus
) {
745 case KWMnoDecoration
:
746 wwin
->client_flags
.no_titlebar
= 1;
747 wwin
->client_flags
.no_resizebar
= 1;
749 case KWMtinyDecoration
:
750 wwin
->client_flags
.no_resizebar
= 1;
752 case KWMstandaloneMenuBar
:
753 wwin
->client_flags
.no_titlebar
= 1;
754 wwin
->client_flags
.no_resizebar
= 1;
755 wwin
->client_flags
.no_resizable
= 1;
756 wwin
->client_flags
.skip_window_list
= 1;
757 wwin
->client_flags
.no_hide_others
= 1;
758 wwin
->flags
.kwm_menubar
= 1;
759 *layer
= WMMainMenuLevel
;
762 *layer
= WMDesktopLevel
;
765 *layer
= WMFloatingLevel
;
767 case KWMnormalDecoration
:
772 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_DESKTOP
, &val
)) {
773 *workspace
= val
- 1;
779 wKWMCheckClientInitialState(WWindow
*wwin
)
784 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_STICKY
, &val
) && val
) {
786 wwin
->client_flags
.omnipresent
= 1;
788 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_ICONIFIED
, &val
) && val
) {
790 wwin
->flags
.miniaturized
= 1;
792 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_MAXIMIZED
, &val
)) {
794 wwin
->flags
.maximized
= MAX_VERTICAL
;
796 wwin
->flags
.maximized
= MAX_HORIZONTAL
;
798 wwin
->flags
.maximized
= MAX_VERTICAL
|MAX_HORIZONTAL
;
800 if (getAreaHint(wwin
->client_win
, _XA_KWM_WIN_GEOMETRY_RESTORE
, &area
)
801 && (wwin
->old_geometry
.x
!= area
.x1
802 || wwin
->old_geometry
.y
!= area
.y1
803 || wwin
->old_geometry
.width
!= area
.x2
- area
.x1
804 || wwin
->old_geometry
.height
!= area
.y2
- area
.y1
)) {
806 wwin
->old_geometry
.x
= area
.x1
;
807 wwin
->old_geometry
.y
= area
.y1
;
808 wwin
->old_geometry
.width
= area
.x2
- area
.x1
;
809 wwin
->old_geometry
.height
= area
.y2
- area
.y1
;
815 wKWMCheckClientHintChange(WWindow
*wwin
, XPropertyEvent
*event
)
817 Bool processed
= True
;
826 if (event
->atom
== _XA_KWM_WIN_UNSAVED_DATA
) {
828 printf("got KDE unsaved data change\n");
831 flag
= getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_UNSAVED_DATA
,
834 if (flag
!= wwin
->client_flags
.broken_close
) {
835 wwin
->client_flags
.broken_close
= flag
;
837 wWindowUpdateButtonImages(wwin
);
839 } else if (event
->atom
== _XA_KWM_WIN_STICKY
) {
842 printf("got KDE sticky change\n");
844 flag
= !getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_STICKY
,
847 if (flag
!= wwin
->client_flags
.omnipresent
) {
849 wwin
->client_flags
.omnipresent
= flag
;
851 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, ACTION_CHANGE_WORKSPACE
);
854 } else if (event
->atom
== _XA_KWM_WIN_MAXIMIZED
) {
858 printf("got KDE maximize change\n");
860 flag
= getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_MAXIMIZED
, &value
);
864 bla
= MAX_VERTICAL
|MAX_HORIZONTAL
;
868 bla
= MAX_HORIZONTAL
;
871 if (bla
!= wwin
->flags
.maximized
) {
873 wMaximizeWindow(wwin
, bla
);
875 wUnmaximizeWindow(wwin
);
877 } else if (event
->atom
== _XA_KWM_WIN_ICONIFIED
) {
880 printf("got KDE iconify change\n");
882 flag
= !getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_ICONIFIED
,
885 if (flag
!= wwin
->flags
.miniaturized
) {
888 wIconifyWindow(wwin
);
890 wDeiconifyWindow(wwin
);
893 } else if (event
->atom
== _XA_KWM_WIN_DECORATION
) {
894 Bool refresh
= False
;
898 printf("got KDE decoration change\n");
901 oldnofocus
= wwin
->client_flags
.no_focusable
;
903 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_DECORATION
, &value
)) {
904 wwin
->client_flags
.no_focusable
= (value
& KWMnoFocus
)!=0;
906 switch (value
& ~KWMnoFocus
) {
907 case KWMnoDecoration
:
908 if (!WFLAGP(wwin
, no_titlebar
) || !WFLAGP(wwin
, no_resizebar
))
911 wwin
->client_flags
.no_titlebar
= 1;
912 wwin
->client_flags
.no_resizebar
= 1;
915 case KWMtinyDecoration
:
916 if (WFLAGP(wwin
, no_titlebar
) || !WFLAGP(wwin
, no_resizebar
))
919 wwin
->client_flags
.no_titlebar
= 0;
920 wwin
->client_flags
.no_resizebar
= 1;
923 case KWMnormalDecoration
:
925 if (WFLAGP(wwin
, no_titlebar
) || WFLAGP(wwin
, no_resizebar
))
928 wwin
->client_flags
.no_titlebar
= 0;
929 wwin
->client_flags
.no_resizebar
= 0;
933 if (WFLAGP(wwin
, no_titlebar
) || WFLAGP(wwin
, no_resizebar
))
935 wwin
->client_flags
.no_focusable
= (value
& KWMnoFocus
)!=0;
936 wwin
->client_flags
.no_titlebar
= 0;
937 wwin
->client_flags
.no_resizebar
= 0;
941 wWindowConfigureBorders(wwin
);
943 if (wwin
->client_flags
.no_focusable
&& !oldnofocus
) {
945 sendToModules(wwin
->screen_ptr
, _XA_KWM_MODULE_WIN_REMOVE
,
947 wwin
->flags
.kwm_hidden_for_modules
= 1;
949 } else if (!wwin
->client_flags
.no_focusable
&& oldnofocus
) {
951 if (wwin
->flags
.kwm_hidden_for_modules
) {
952 sendToModules(wwin
->screen_ptr
, _XA_KWM_MODULE_WIN_ADD
,
954 wwin
->flags
.kwm_hidden_for_modules
= 0;
957 } else if (event
->atom
== _XA_KWM_WIN_DESKTOP
&& wwin
->frame
) {
959 printf("got KDE workspace change for %s\n", wwin
->frame
->title
);
961 if (getSimpleHint(wwin
->client_win
, _XA_KWM_WIN_DESKTOP
, &value
)
962 && value
-1 != wwin
->frame
->workspace
) {
963 wWindowChangeWorkspace(wwin
, value
-1);
966 } else if (event
->atom
== _XA_KWM_WIN_GEOMETRY_RESTORE
) {
970 printf("got KDE geometry restore change\n");
972 if (getAreaHint(wwin
->client_win
, _XA_KWM_WIN_GEOMETRY_RESTORE
, &area
)
973 && (wwin
->old_geometry
.x
!= area
.x1
974 || wwin
->old_geometry
.y
!= area
.y1
975 || wwin
->old_geometry
.width
!= area
.x2
- area
.x1
976 || wwin
->old_geometry
.height
!= area
.y2
- area
.y1
)) {
978 wwin
->old_geometry
.x
= area
.x1
;
979 wwin
->old_geometry
.y
= area
.y1
;
980 wwin
->old_geometry
.width
= area
.x2
- area
.x1
;
981 wwin
->old_geometry
.height
= area
.y2
- area
.y1
;
992 performWindowCommand(WScreen
*scr
, char *command
)
994 WWindow
*wwin
= NULL
;
997 wwin
= scr
->focused_window
;
998 if (!wwin
|| !wwin
->flags
.focused
|| !wwin
->flags
.mapped
) {
1002 CloseWindowMenu(scr
);
1005 if (strcmp(command
, "winMove")==0 || strcmp(command
, "winResize")==0) {
1008 wKeyboardMoveResizeWindow(wwin
);
1010 } else if (strcmp(command
, "winMaximize")==0) {
1013 wMaximizeWindow(wwin
, MAX_VERTICAL
|MAX_HORIZONTAL
);
1015 } else if (strcmp(command
, "winRestore")==0) {
1017 if (wwin
&& wwin
->flags
.maximized
)
1018 wUnmaximizeWindow(wwin
);
1020 } else if (strcmp(command
, "winIconify")==0) {
1023 if (wwin
&& !WFLAGP(wwin
, no_miniaturizable
)) {
1024 if (wwin
->protocols
.MINIATURIZE_WINDOW
)
1025 wClientSendProtocol(wwin
, _XA_GNUSTEP_WM_MINIATURIZE_WINDOW
,
1028 wIconifyWindow(wwin
);
1032 } else if (strcmp(command
, "winClose")==0) {
1034 if (wwin
&& !WFLAGP(wwin
, no_closable
)) {
1035 if (wwin
->protocols
.DELETE_WINDOW
)
1036 wClientSendProtocol(wwin
, _XA_WM_DELETE_WINDOW
, LastTimestamp
);
1039 } else if (strcmp(command
, "winSticky")==0) {
1042 wwin
->client_flags
.omnipresent
^= 1;
1043 UpdateSwitchMenu(scr
, wwin
, ACTION_CHANGE_WORKSPACE
);
1046 } else if (strcmp(command
, "winShade")==0) {
1048 if (wwin
&& !WFLAGP(wwin
, no_shadeable
)) {
1049 if (wwin
->flags
.shaded
)
1050 wUnshadeWindow(wwin
);
1055 } else if (strcmp(command
, "winOperation")==0) {
1058 OpenWindowMenu(wwin
, wwin
->frame_x
,
1059 wwin
->frame_y
+wwin
->frame
->top_width
, True
);
1070 performCommand(WScreen
*scr
, char *command
, XClientMessageEvent
*event
)
1072 assert(scr
!= NULL
);
1074 if (strcmp(command
, "commandLine")==0
1075 || strcmp(command
, "execute")==0) {
1078 cmd
= ExpandOptions(scr
, _("%a(Run Command,Type the command to run:)"));
1080 ExecuteShellCommand(scr
, cmd
);
1083 } else if (strcmp(command
, "logout")==0) {
1085 Shutdown(WSLogoutMode
);
1087 } else if (strcmp(command
, "refreshScreen")==0) {
1089 wRefreshDesktop(scr
);
1091 } else if (strncmp(command
, "go:", 3)==0) {
1093 Shutdown(WSRestartPreparationMode
);
1094 Restart(&command
[3], False
);
1095 Restart(NULL
, True
);
1097 } else if (strcmp(command
, "desktop+1")==0) {
1099 wWorkspaceRelativeChange(scr
, 1);
1101 } else if (strcmp(command
, "desktop-1")==0) {
1103 wWorkspaceRelativeChange(scr
, -1);
1105 } else if (strcmp(command
, "desktop+2")==0) {
1107 wWorkspaceRelativeChange(scr
, 2);
1109 } else if (strcmp(command
, "desktop-2")==0) {
1111 wWorkspaceRelativeChange(scr
, -2);
1113 } else if (strcmp(command
, "desktop%%2")==0) {
1115 if (scr
->current_workspace
% 2 == 1)
1116 wWorkspaceRelativeChange(scr
, 1);
1118 wWorkspaceRelativeChange(scr
, -1);
1119 } else if (strncmp(command
, "desktop", 7)==0) {
1122 ws
= atoi(&command
[7]);
1123 wWorkspaceChange(scr
, ws
);
1125 /* wmaker specific stuff */
1126 } else if (strcmp(command
, "wmaker:info")==0) {
1128 wShowInfoPanel(scr
);
1130 } else if (strcmp(command
, "wmaker:legal")==0) {
1132 wShowLegalPanel(scr
);
1134 } else if (strcmp(command
, "wmaker:arrangeIcons")==0) {
1136 wArrangeIcons(scr
, True
);
1138 } else if (strcmp(command
, "wmaker:showAll")==0) {
1140 wShowAllWindows(scr
);
1142 } else if (strcmp(command
, "wmaker:hideOthers")==0) {
1144 wHideOtherApplications(scr
->focused_window
);
1146 } else if (strcmp(command
, "wmaker:restart")==0) {
1148 Shutdown(WSRestartPreparationMode
);
1149 Restart(NULL
, True
);
1151 } else if (strcmp(command
, "wmaker:exit")==0) {
1153 Shutdown(WSExitMode
);
1155 #ifdef UNSUPPORTED_STUFF
1156 } else if (strcmp(command
, "moduleRaised")==0) { /* useless */
1157 } else if (strcmp(command
, "deskUnclutter")==0) {
1158 } else if (strcmp(command
, "deskCascade")==0) {
1159 } else if (strcmp(command
, "configure")==0) {
1160 } else if (strcmp(command
, "taskManager")==0) {
1161 } else if (strcmp(command
, "darkenScreen")==0) { /* breaks consistency */
1163 } else if (!performWindowCommand(scr
, command
)) {
1164 KWMModuleList
*module
;
1167 /* do message relay thing */
1169 ev
.xclient
= *event
;
1170 for (module
= KWMModules
; module
!= NULL
; module
= module
->next
) {
1172 ev
.xclient
.window
= module
->window
;
1173 if (module
->window
== scr
->root_win
)
1174 mask
= SubstructureRedirectMask
;
1178 XSendEvent(dpy
, module
->window
, False
, mask
, &ev
);
1185 wKWMProcessClientMessage(XClientMessageEvent
*event
)
1187 Bool processed
= True
;
1190 printf("CLIENT MESS %s\n", XGetAtomName(dpy
, event
->message_type
));
1192 if (event
->message_type
== _XA_KWM_COMMAND
&& event
->format
==8) {
1196 scr
= wScreenForRootWindow(event
->window
);
1198 for (i
=0; i
<20; i
++) {
1199 buffer
[i
] = event
->data
.b
[i
];
1204 printf("got KDE command %s\n", buffer
);
1206 performCommand(scr
, buffer
, event
);
1208 } else if (event
->message_type
== _XA_KWM_ACTIVATE_WINDOW
) {
1212 printf("got KDE activate internal\n");
1214 wwin
= wWindowFor(event
->data
.l
[0]);
1217 wSetFocusTo(wwin
->screen_ptr
, wwin
);
1219 } else if (event
->message_type
== _XA_KWM_DO_NOT_MANAGE
1220 && event
->format
== 8) {
1221 KWMDoNotManageList
*node
;
1225 printf("got KDE dont manage\n");
1228 node
= malloc(sizeof(KWMDoNotManageList
));
1230 wwarning("out of memory processing KWM_DO_NOT_MANAGE message");
1232 for (i
=0; i
<20 && event
->data
.b
[i
]; i
++)
1233 node
->title
[i
] = event
->data
.b
[i
];
1236 node
->next
= KWMDoNotManageCrap
;
1237 KWMDoNotManageCrap
= node
;
1239 } else if (event
->message_type
== _XA_KWM_MODULE
) {
1241 Window modwin
= event
->data
.l
[0];
1243 scr
= wScreenForRootWindow(event
->window
);
1245 if (getSimpleHint(modwin
, _XA_KWM_MODULE
, &val
) && val
) {
1247 puts("got KDE module startup");
1249 addModule(scr
, modwin
);
1252 puts("got KDE module finish");
1254 removeModule(scr
, modwin
);
1265 wKWMCheckModule(WScreen
*scr
, Window window
)
1269 if (getSimpleHint(window
, _XA_KWM_MODULE
, &val
) && val
) {
1271 puts("got KDE module startup");
1273 addModule(scr
, window
);
1279 wKWMCheckRootHintChange(WScreen
*scr
, XPropertyEvent
*event
)
1281 Bool processed
= True
;
1284 if (event
->atom
== _XA_KWM_CURRENT_DESKTOP
) {
1285 if (getSimpleHint(scr
->root_win
, _XA_KWM_CURRENT_DESKTOP
, &value
)) {
1287 printf("got KDE workspace switch to %li\n", value
);
1289 if (value
-1 != scr
->current_workspace
) {
1290 wWorkspaceChange(scr
, value
-1);
1293 } else if (event
->atom
== _XA_KWM_NUMBER_OF_DESKTOPS
) {
1295 printf("got KDE workspace number change\n");
1298 if (getSimpleHint(scr
->root_win
, _XA_KWM_NUMBER_OF_DESKTOPS
, &value
)) {
1300 /* increasing is easy... */
1301 if (value
> scr
->workspace_count
) {
1302 scr
->flags
.kwm_syncing_count
= 1;
1304 wWorkspaceMake(scr
, value
- scr
->workspace_count
);
1306 scr
->flags
.kwm_syncing_count
= 0;
1308 } else if (value
< scr
->workspace_count
) {
1310 Bool rebuild
= False
;
1312 scr
->flags
.kwm_syncing_count
= 1;
1314 /* decrease all we can do */
1315 for (i
= scr
->workspace_count
; i
>= value
; i
--) {
1316 if (!wWorkspaceDelete(scr
, i
)) {
1322 scr
->flags
.kwm_syncing_count
= 0;
1324 /* someone destroyed a workspace that can't be destroyed.
1325 * Reset the hints to reflect our internal state.
1328 wKWMUpdateWorkspaceCountHint(scr
);
1337 for (i
= 0; i
< MAX_WORKSPACES
&& i
< scr
->workspace_count
; i
++) {
1338 if (event
->atom
== _XA_KWM_DESKTOP_NAME_
[i
]) {
1341 name
= wKWMGetWorkspaceName(scr
, i
);
1344 printf("got KDE workspace name change to %s\n", name
);
1347 if (name
&& strncmp(name
, scr
->workspaces
[i
]->name
,
1348 MAX_WORKSPACENAME_WIDTH
)!=0) {
1349 scr
->flags
.kwm_syncing_name
= 1;
1350 wWorkspaceRename(scr
, i
, name
);
1351 scr
->flags
.kwm_syncing_name
= 0;
1357 } else if (event
->atom
== _XA_KWM_WINDOW_REGION_
[i
]) {
1360 if (getAreaHint(scr
->root_win
, event
->atom
, &area
)) {
1362 if (scr
->totalUsableArea
.x1
!= area
.x1
1363 || scr
->totalUsableArea
.y1
!= area
.y1
1364 || scr
->totalUsableArea
.x2
!= area
.x2
1365 || scr
->totalUsableArea
.y2
!= area
.y2
) {
1366 wScreenUpdateUsableArea(scr
);
1381 wKWMManageableClient(WScreen
*scr
, Window win
, char *title
)
1383 KWMDoNotManageList
*ptr
, *next
;
1386 if (getSimpleHint(win
, _XA_KWM_DOCKWINDOW
, &val
) && val
) {
1387 addDockWindow(scr
, win
);
1391 ptr
= KWMDoNotManageCrap
;
1393 * TODO: support for glob patterns or regexes
1395 if (ptr
&& strncmp(ptr
->title
, title
, strlen(ptr
->title
))==0) {
1398 KWMDoNotManageCrap
= next
;
1400 printf("window %s not managed per KDE request\n", title
);
1403 sendToModules(scr
, _XA_KWM_MODULE_WIN_ADD
, NULL
, win
);
1404 sendToModules(scr
, _XA_KWM_MODULE_WIN_REMOVE
, NULL
, win
);
1409 if (strncmp(ptr
->next
->title
, title
, strlen(ptr
->next
->title
))==0) {
1411 printf("window %s not managed per KDE request\n", title
);
1413 next
= ptr
->next
->next
;
1417 sendToModules(scr
, _XA_KWM_MODULE_WIN_ADD
, NULL
, win
);
1418 sendToModules(scr
, _XA_KWM_MODULE_WIN_REMOVE
, NULL
, win
);
1432 wKWMUpdateCurrentWorkspaceHint(WScreen
*scr
)
1434 setSimpleHint(scr
->root_win
, _XA_KWM_CURRENT_DESKTOP
,
1435 scr
->current_workspace
+1);
1437 sendToModules(scr
, _XA_KWM_MODULE_DESKTOP_CHANGE
, NULL
,
1438 scr
->current_workspace
+1);
1443 wKWMUpdateActiveWindowHint(WScreen
*scr
)
1446 WWindow
*wwin
, *tmp
;
1448 if (!scr
->focused_window
|| !scr
->focused_window
->flags
.focused
)
1451 val
= (long)(scr
->focused_window
->client_win
);
1453 /* raise the menubar thing */
1454 wwin
= scr
->focused_window
;
1457 if (tmp
->flags
.kwm_menubar
1458 && tmp
->transient_for
== wwin
->client_win
) {
1459 wRaiseFrame(tmp
->frame
->core
);
1466 XChangeProperty(dpy
, scr
->root_win
, _XA_KWM_ACTIVE_WINDOW
,
1467 _XA_KWM_ACTIVE_WINDOW
, 32, PropModeReplace
,
1468 (unsigned char*)&val
, 1);
1474 wKWMUpdateWorkspaceCountHint(WScreen
*scr
)
1476 if (scr
->flags
.kwm_syncing_count
)
1479 setSimpleHint(scr
->root_win
, _XA_KWM_NUMBER_OF_DESKTOPS
,
1480 scr
->workspace_count
);
1482 sendToModules(scr
, _XA_KWM_MODULE_DESKTOP_NUMBER_CHANGE
, NULL
,
1483 scr
->workspace_count
);
1488 wKWMCheckDestroy(XDestroyWindowEvent
*event
)
1492 if (event
->event
== event
->window
) {
1496 scr
= wScreenSearchForRootWindow(event
->event
);
1501 removeModule(scr
, event
->window
);
1502 removeDockWindow(scr
, event
->window
);
1507 wKWMUpdateWorkspaceNameHint(WScreen
*scr
, int workspace
)
1511 assert(workspace
>= 0 && workspace
< MAX_WORKSPACES
);
1513 if (_XA_KWM_DESKTOP_NAME_
[workspace
]==0) {
1514 sprintf(buffer
, "KWM_DESKTOP_NAME_%d", workspace
+ 1);
1516 _XA_KWM_DESKTOP_NAME_
[workspace
] = XInternAtom(dpy
, buffer
, False
);
1519 XChangeProperty(dpy
, scr
->root_win
, _XA_KWM_DESKTOP_NAME_
[workspace
],
1520 XA_STRING
, 8, PropModeReplace
,
1521 (unsigned char*)scr
->workspaces
[workspace
]->name
,
1522 strlen(scr
->workspaces
[workspace
]->name
)+1);
1524 sendToModules(scr
, _XA_KWM_MODULE_DESKTOP_NAME_CHANGE
, NULL
, workspace
+1);
1530 wKWMUpdateClientWorkspace(WWindow
*wwin
)
1533 printf("updating workspace of %s to %i\n",
1534 wwin
->frame
->title
, wwin
->frame
->workspace
+1);
1536 setSimpleHint(wwin
->client_win
, _XA_KWM_WIN_DESKTOP
,
1537 wwin
->frame
->workspace
+1);
1542 wKWMUpdateClientGeometryRestore(WWindow
*wwin
)
1546 rect
.x1
= wwin
->old_geometry
.x
;
1547 rect
.y1
= wwin
->old_geometry
.y
;
1548 rect
.x2
= wwin
->old_geometry
.x
+ wwin
->old_geometry
.width
;
1549 rect
.y2
= wwin
->old_geometry
.y
+ wwin
->old_geometry
.height
;
1551 setAreaHint(wwin
->client_win
, _XA_KWM_WIN_GEOMETRY_RESTORE
, rect
);
1556 wKWMUpdateClientStateHint(WWindow
*wwin
, WKWMStateFlag flags
)
1558 if (flags
& KWMIconifiedFlag
) {
1559 setSimpleHint(wwin
->client_win
, _XA_KWM_WIN_ICONIFIED
,
1560 wwin
->flags
.miniaturized
/*|| wwin->flags.shaded
1561 || wwin->flags.hidden*/);
1563 if (flags
& KWMStickyFlag
) {
1564 setSimpleHint(wwin
->client_win
, _XA_KWM_WIN_STICKY
,
1565 IS_OMNIPRESENT(wwin
));
1567 if (flags
& KWMMaximizedFlag
) {
1570 if (wwin
->flags
.maximized
& MAX_VERTICAL
)
1572 if (wwin
->flags
.maximized
& MAX_HORIZONTAL
)
1575 setSimpleHint(wwin
->client_win
, _XA_KWM_WIN_MAXIMIZED
, value
);
1581 wKWMGetUsableArea(WScreen
*scr
, WArea
*area
)
1585 if (_XA_KWM_WINDOW_REGION_
[0]==0) {
1586 sprintf(buffer
, "KWM_WINDOW_REGION_%d", 1);
1588 _XA_KWM_WINDOW_REGION_
[0] = XInternAtom(dpy
, buffer
, False
);
1591 return getAreaHint(scr
->root_win
, _XA_KWM_WINDOW_REGION_
[0], area
);
1597 wKWMGetIconGeometry(WWindow
*wwin
, WArea
*area
)
1599 return getAreaHint(wwin
->client_win
, _XA_KWM_WIN_ICON_GEOMETRY
, area
);
1606 wKWMSetUsableAreaHint(WScreen
*scr
, int workspace
)
1608 /* if we set this after making changes of our own to the area,
1609 * the next time the area changes, we won't know what should
1610 * be the new final area. This protocol isn't worth a shit :/
1613 * According to Matthias Ettrich:
1614 * Indeed, there's no protocol to deal with the area yet in case several
1615 * clients want to influence it. It is sufficent, though, if it is clear
1616 * that one process is responsable for the area. For KDE this is kpanel, but
1617 * I see that there might be a conflict with the docking area of windowmaker
1625 assert(workspace
>= 0 && workspace
< MAX_WORKSPACES
);
1627 if (_XA_KWM_WINDOW_REGION_
[workspace
]==0) {
1628 sprintf(buffer
, "KWM_WINDOW_REGION_%d", workspace
+1);
1630 _XA_KWM_WINDOW_REGION_
[workspace
] = XInternAtom(dpy
, buffer
, False
);
1633 setAreaHint(scr
->root_win
, _XA_KWM_WINDOW_REGION_
[workspace
],
1634 scr
->totalUsableArea
);
1637 #endif /* not_used */
1640 wKWMSendEventMessage(WWindow
*wwin
, WKWMEventMessage message
)
1644 if (wwin
&& (wwin
->flags
.internal_window
1645 || wwin
->flags
.kwm_hidden_for_modules
1646 || !wwin
->flags
.kwm_managed
1647 || WFLAGP(wwin
, skip_window_list
)))
1652 msg
= _XA_KWM_MODULE_WIN_ADD
;
1654 case WKWMRemoveWindow
:
1655 msg
= _XA_KWM_MODULE_WIN_REMOVE
;
1657 case WKWMFocusWindow
:
1658 msg
= _XA_KWM_MODULE_WIN_ACTIVATE
;
1660 case WKWMRaiseWindow
:
1661 msg
= _XA_KWM_MODULE_WIN_RAISE
;
1663 case WKWMLowerWindow
:
1664 msg
= _XA_KWM_MODULE_WIN_LOWER
;
1666 case WKWMChangedClient
:
1667 msg
= _XA_KWM_MODULE_WIN_CHANGE
;
1669 case WKWMIconChange
:
1670 msg
= _XA_KWM_MODULE_WIN_ICON_CHANGE
;
1676 sendToModules(wwin
? wwin
->screen_ptr
: NULL
, msg
, wwin
, 0);
1681 writeSocket(int sock
, char *data
)
1685 sprintf(buffer
, "%i ", strlen(data
));
1686 write(sock
, buffer
, strlen(buffer
));
1687 write(sock
, data
, strlen(data
));
1692 connectKFM(WScreen
*scr
)
1700 struct sockaddr_un addr
;
1702 path
= wstrconcat(wgethomedir(), "/.kde/share/apps/kfm/pid");
1703 strcpy(buffer
, getenv("DISPLAY"));
1705 ptr
= strchr(buffer
, ':');
1709 ptr
= strrchr(buffer
, '.');
1715 sprintf(b
, ".%i", scr
->screen
);
1719 path
= wstrconcat(ptr
, buffer
);
1723 f
= fopen(path
, "r");
1729 fgets(buffer
, 123, f
);
1734 if (kill(pid
, 0) != 0)
1738 fscanf(f
, "%s", buffer
);
1741 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
1744 addr
.sun_family
= AF_UNIX
;
1745 strcpy(addr
.sun_path
, buffer
);
1747 if (connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
1752 path
= wstrconcat(wgethomedir(), "/.kde/share/apps/kfm/magic");
1753 f
= fopen(path
, "r");
1757 ptr
= fgets(buffer
, 123, f
);
1764 ptr
= wstrconcat("auth", buffer
);
1766 writeSocket(sock
, ptr
);
1774 wKWMSelectRootRegion(WScreen
*scr
, int x
, int y
, int w
, int h
, Bool control
)
1781 sock
= connectKFM(scr
);
1784 puts("SENDING DATA");
1786 sprintf(buffer
, "selectRootIcons %i %i %i %i %c", x
, y
, w
, h
, control
);
1787 writeSocket(sock
, buffer
);
1794 #endif /* KWM_HINTS */