9 typedef struct W_Window
{
13 struct W_Window
*nextPtr
; /* next in the window list */
15 struct W_Window
*owner
;
19 WMPixmap
*miniImage
; /* miniwindow */
24 WMSize resizeIncrement
;
29 WMAction
*closeAction
;
36 unsigned configured
:1;
37 unsigned documentEdited
:1;
49 Pixmap miniaturize_pixmap
; /* pixmap for miniaturize button */
50 Pixmap close_pixmap
; /* pixmap for close button */
51 Pixmap miniaturize_mask
; /* miniaturize pixmap mask */
52 Pixmap close_mask
; /* close pixmap mask */
54 } GNUstepWMAttributes
;
56 #define GSWindowStyleAttr (1<<0)
57 #define GSWindowLevelAttr (1<<1)
58 #define GSMiniaturizePixmapAttr (1<<3)
59 #define GSClosePixmapAttr (1<<4)
60 #define GSMiniaturizeMaskAttr (1<<5)
61 #define GSCloseMaskAttr (1<<6)
62 #define GSExtraFlagsAttr (1<<7)
65 #define GSDocumentEditedFlag (1<<0)
66 #define GSNoApplicationIconFlag (1<<5)
68 #define WMFHideOtherApplications 10
69 #define WMFHideApplication 12
73 static void resizeWindow(WMWidget
*, unsigned, unsigned);
74 static void moveWindow(WMWidget
*, int, int);
76 struct W_ViewProcedureTable _WindowViewProcedures
= {
83 #define DEFAULT_WIDTH 400
84 #define DEFAULT_HEIGHT 180
85 #define DEFAULT_TITLE ""
88 static void destroyWindow(_Window
*win
);
90 static void handleEvents();
92 static void realizeWindow();
95 realizeObserver(void *self
, WMNotification
*not)
102 WMCreatePanelWithStyleForWindow(WMWindow
*owner
, char *name
, int style
)
106 win
= WMCreateWindowWithStyle(owner
->view
->screen
, name
, style
);
115 WMCreatePanelForWindow(WMWindow
*owner
, char *name
)
117 return WMCreatePanelWithStyleForWindow(owner
, name
,
119 |WMClosableWindowMask
120 |WMResizableWindowMask
);
125 WMChangePanelOwner(WMWindow
*win
, WMWindow
*newOwner
)
127 win
->owner
= newOwner
;
129 if (win
->view
->flags
.realized
&& newOwner
) {
130 XSetTransientForHint(win
->view
->screen
->display
, win
->view
->window
,
131 newOwner
->view
->window
);
138 WMCreateWindow(WMScreen
*screen
, char *name
)
140 return WMCreateWindowWithStyle(screen
, name
, WMTitledWindowMask
141 |WMClosableWindowMask
142 |WMMiniaturizableWindowMask
143 |WMResizableWindowMask
);
149 WMCreateWindowWithStyle(WMScreen
*screen
, char *name
, int style
)
152 static int initedApp
= 0;
154 win
= wmalloc(sizeof(_Window
));
155 memset(win
, 0, sizeof(_Window
));
157 win
->widgetClass
= WC_Window
;
159 win
->view
= W_CreateTopView(screen
);
164 win
->view
->self
= win
;
166 win
->wname
= wstrdup(name
);
168 /* add to the window list of the screen (application) */
169 win
->nextPtr
= screen
->windowList
;
170 screen
->windowList
= win
;
172 WMCreateEventHandler(win
->view
, ExposureMask
|StructureNotifyMask
173 |ClientMessageMask
|FocusChangeMask
, handleEvents
,
176 W_ResizeView(win
->view
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
179 W_InitApplication(screen
);
183 WMAddNotificationObserver(realizeObserver
, win
,
184 WMViewRealizedNotification
, win
->view
);
186 win
->flags
.style
= style
;
188 win
->level
= WMNormalWindowLevel
;
190 /* kluge. Find a better solution */
191 W_SetFocusOfTopLevel(win
->view
, win
->view
);
198 WMSetWindowTitle(WMWindow
*win
, char *title
)
200 if (win
->title
!=NULL
)
203 win
->title
= wstrdup(title
);
207 if (win
->view
->flags
.realized
) {
208 XStoreName(win
->view
->screen
->display
, win
->view
->window
, title
);
216 WMSetWindowCloseAction(WMWindow
*win
, WMAction
*action
, void *clientData
)
221 WMScreen
*scr
= win
->view
->screen
;
223 if (win
->view
->flags
.realized
) {
224 if (action
&& !win
->closeAction
) {
225 if (!XGetWMProtocols(scr
->display
, win
->view
->window
, &atoms
,
229 newAtoms
= wmalloc((count
+1)*sizeof(Atom
));
231 memcpy(newAtoms
, atoms
, count
*sizeof(Atom
));
232 newAtoms
[count
++] = scr
->deleteWindowAtom
;
233 XSetWMProtocols(scr
->display
, win
->view
->window
, newAtoms
, count
);
237 } else if (!action
&& win
->closeAction
) {
240 if (XGetWMProtocols(scr
->display
, win
->view
->window
, &atoms
,
241 &count
) && count
>0) {
242 newAtoms
= wmalloc((count
-1)*sizeof(Atom
));
244 for (i
=0; i
< count
; i
++) {
245 if (atoms
[i
]!=scr
->deleteWindowAtom
) {
246 newAtoms
[i
] = atoms
[i
];
250 XSetWMProtocols(scr
->display
, win
->view
->window
, newAtoms
,
258 win
->closeAction
= action
;
259 win
->closeData
= clientData
;
264 moveWindow(WMWidget
*w
, int x
, int y
)
266 ((WMWindow
*)w
)->flags
.moved
= 1;
268 W_MoveView(W_VIEW(w
), x
, y
);
273 resizeWindow(WMWidget
*w
, unsigned width
, unsigned height
)
275 WMWindow
*win
= (WMWindow
*)w
;
277 if (win
->minSize
.width
> 0 && win
->minSize
.height
> 0) {
278 if (width
< win
->minSize
.width
)
279 width
= win
->minSize
.width
;
280 if (height
< win
->minSize
.height
)
281 height
= win
->minSize
.height
;
284 if (win
->maxSize
.width
> 0 && win
->maxSize
.height
> 0) {
285 if (width
> win
->maxSize
.width
)
286 width
= win
->maxSize
.width
;
287 if (height
> win
->maxSize
.height
)
288 height
= win
->maxSize
.height
;
291 W_ResizeView(win
->view
, width
, height
);
296 setSizeHints(WMWindow
*win
)
300 hints
= XAllocSizeHints();
302 wwarning("could not allocate memory for window size hints");
307 if (win
->minSize
.width
>0 && win
->minSize
.height
>0) {
308 hints
->flags
|= PMinSize
;
309 hints
->min_width
= win
->minSize
.width
;
310 hints
->min_height
= win
->minSize
.height
;
312 if (win
->maxSize
.width
>0 && win
->maxSize
.height
>0) {
313 hints
->flags
|= PMaxSize
;
314 hints
->max_width
= win
->maxSize
.width
;
315 hints
->max_height
= win
->maxSize
.height
;
317 if (win
->baseSize
.width
>0 && win
->baseSize
.height
>0) {
318 hints
->flags
|= PBaseSize
;
319 hints
->base_width
= win
->baseSize
.width
;
320 hints
->base_height
= win
->baseSize
.height
;
322 if (win
->resizeIncrement
.width
>0 && win
->resizeIncrement
.height
>0) {
323 hints
->flags
|= PResizeInc
;
324 hints
->width_inc
= win
->resizeIncrement
.width
;
325 hints
->height_inc
= win
->resizeIncrement
.height
;
329 XSetWMNormalHints(win
->view
->screen
->display
, win
->view
->window
, hints
);
337 writeGNUstepWMAttr(WMScreen
*scr
, Window window
, GNUstepWMAttributes
*attr
)
341 /* handle idiot compilers where array of CARD32 != struct of CARD32 */
342 data
[0] = attr
->flags
;
343 data
[1] = attr
->window_style
;
344 data
[2] = attr
->window_level
;
345 data
[3] = 0; /* reserved */
346 /* The X protocol says XIDs are 32bit */
347 data
[4] = attr
->miniaturize_pixmap
;
348 data
[5] = attr
->close_pixmap
;
349 data
[6] = attr
->miniaturize_mask
;
350 data
[7] = attr
->close_mask
;
351 data
[8] = attr
->extra_flags
;
352 XChangeProperty(scr
->display
, window
, scr
->attribsAtom
, scr
->attribsAtom
,
353 32, PropModeReplace
, (unsigned char *)data
, 9);
358 setWindowMakerHints(WMWindow
*win
)
360 GNUstepWMAttributes attribs
;
361 WMScreen
*scr
= WMWidgetScreen(win
);
363 memset(&attribs
, 0, sizeof(GNUstepWMAttributes
));
364 attribs
.flags
= GSWindowStyleAttr
|GSWindowLevelAttr
|GSExtraFlagsAttr
;
365 attribs
.window_style
= win
->flags
.style
;
366 attribs
.window_level
= win
->level
;
367 if (win
->flags
.documentEdited
)
368 attribs
.extra_flags
= GSDocumentEditedFlag
;
370 attribs
.extra_flags
= 0;
372 writeGNUstepWMAttr(scr
, win
->view
->window
, &attribs
);
377 realizeWindow(WMWindow
*win
)
380 XClassHint
*classHint
;
381 WMScreen
*scr
= win
->view
->screen
;
385 if (!win
->flags
.moved
&& win
->owner
!=NULL
) {
386 W_MoveView(win
->view
,
387 (scr
->rootView
->size
.width
-win
->view
->size
.width
)/2,
388 (scr
->rootView
->size
.height
-win
->view
->size
.height
)/2);
391 classHint
= XAllocClassHint();
392 classHint
->res_name
= win
->wname
;
393 classHint
->res_class
= WMGetApplicationName();
394 XSetClassHint(scr
->display
, win
->view
->window
, classHint
);
397 hints
= XAllocWMHints();
399 if (!scr
->aflags
.simpleApplication
) {
400 hints
->flags
|= WindowGroupHint
;
401 hints
->window_group
= scr
->groupLeader
;
403 if (win
->miniImage
) {
404 hints
->flags
|= IconPixmapHint
;
405 hints
->icon_pixmap
= WMGetPixmapXID(win
->miniImage
);
406 hints
->icon_mask
= WMGetPixmapMaskXID(win
->miniImage
);
407 if (hints
->icon_mask
!= None
) {
408 hints
->flags
|= IconMaskHint
;
411 if (hints
->flags
!= 0)
412 XSetWMHints(scr
->display
, win
->view
->window
, hints
);
416 if (win
->closeAction
) {
417 atoms
[count
++] = scr
->deleteWindowAtom
;
421 XSetWMProtocols(scr
->display
, win
->view
->window
, atoms
, count
);
424 XStoreName(scr
->display
, win
->view
->window
, win
->title
);
427 XSetIconName(scr
->display
, win
->view
->window
, win
->miniTitle
);
429 setWindowMakerHints(win
);
434 XSetTransientForHint(scr
->display
, win
->view
->window
,
435 win
->owner
->view
->window
);
441 WMHideWindow(WMWindow
*win
)
444 XWithdrawWindow(win
->view
->screen
->display
, win
->view
->window
,
445 win
->view
->screen
->screen
);
450 WMSetWindowMinSize(WMWindow
*win
, unsigned width
, unsigned height
)
452 win
->minSize
.width
= width
;
453 win
->minSize
.height
= height
;
454 if (win
->view
->flags
.realized
)
461 WMSetWindowMaxSize(WMWindow
*win
, unsigned width
, unsigned height
)
463 win
->maxSize
.width
= width
;
464 win
->maxSize
.height
= height
;
465 if (win
->view
->flags
.realized
)
471 WMSetWindowBaseSize(WMWindow
*win
, unsigned width
, unsigned height
)
473 /* TODO: validate sizes */
474 win
->baseSize
.width
= width
;
475 win
->baseSize
.height
= height
;
476 if (win
->view
->flags
.realized
)
482 WMSetWindowResizeIncrements(WMWindow
*win
, unsigned wIncr
, unsigned hIncr
)
484 win
->resizeIncrement
.width
= wIncr
;
485 win
->resizeIncrement
.height
= hIncr
;
486 if (win
->view
->flags
.realized
)
492 WMSetWindowLevel(WMWindow
*win
, int level
)
495 if (win
->view
->flags
.realized
)
496 setWindowMakerHints(win
);
501 WMSetWindowDocumentEdited(WMWindow
*win
, Bool flag
)
503 if (win
->flags
.documentEdited
!= flag
) {
504 win
->flags
.documentEdited
= flag
;
505 if (win
->view
->flags
.realized
)
506 setWindowMakerHints(win
);
512 WMSetWindowMiniwindowImage(WMWindow
*win
, WMPixmap
*pixmap
)
514 if ((win
->miniImage
&& !pixmap
) || (!win
->miniImage
&& pixmap
)) {
516 WMReleasePixmap(win
->miniImage
);
519 win
->miniImage
= WMRetainPixmap(pixmap
);
521 win
->miniImage
= NULL
;
523 if (win
->view
->flags
.realized
) {
526 hints
= XGetWMHints(win
->view
->screen
->display
, win
->view
->window
);
528 hints
= XAllocWMHints();
530 wwarning("could not allocate memory for WM hints");
536 hints
->flags
|= IconPixmapHint
;
537 hints
->icon_pixmap
= WMGetPixmapXID(pixmap
);
538 hints
->icon_mask
= WMGetPixmapMaskXID(pixmap
);
539 if (hints
->icon_mask
!= None
) {
540 hints
->flags
|= IconMaskHint
;
543 XSetWMHints(win
->view
->screen
->display
, win
->view
->window
, hints
);
551 WMSetWindowMiniwindowTitle(WMWindow
*win
, char *title
)
553 if ((win
->miniTitle
&& !title
) || (!win
->miniTitle
&& title
)
554 || (title
&& win
->miniTitle
&& strcoll(title
, win
->miniTitle
)!=0)) {
556 free(win
->miniTitle
);
559 win
->miniTitle
= wstrdup(title
);
561 win
->miniTitle
= NULL
;
563 if (win
->view
->flags
.realized
) {
564 XSetIconName(win
->view
->screen
->display
, win
->view
->window
, title
);
571 WMCloseWindow(WMWindow
*win
)
573 /* withdraw the window */
574 if (win
->view
->flags
.realized
)
575 XWithdrawWindow(win
->view
->screen
->display
, win
->view
->window
,
576 win
->view
->screen
->screen
);
581 handleEvents(XEvent
*event
, void *clientData
)
583 _Window
*win
= (_Window
*)clientData
;
586 switch (event
->type
) {
588 if (event
->xclient
.message_type
== win
->view
->screen
->protocolsAtom
589 && event
->xclient
.format
== 32
590 && event
->xclient
.data
.l
[0]==win
->view
->screen
->deleteWindowAtom
) {
592 if (win
->closeAction
) {
593 (*win
->closeAction
)(win
, win
->closeData
);
607 destroyWindow(_Window
*win
)
609 WMScreen
*scr
= win
->view
->screen
;
611 WMRemoveNotificationObserver(win
);
613 if (scr
->windowList
== win
) {
614 scr
->windowList
= scr
->windowList
->nextPtr
;
617 ptr
= scr
->windowList
;
619 while (ptr
->nextPtr
) {
620 if (ptr
->nextPtr
==win
) {
621 ptr
->nextPtr
= ptr
->nextPtr
->nextPtr
;
632 if (win
->miniTitle
) {
633 free(win
->miniTitle
);
636 if (win
->miniImage
) {
637 WMReleasePixmap(win
->miniImage
);