8 #include <X11/Intrinsic.h>
10 #include <X11/Xproto.h>
12 #include "libs/FEvent.h"
18 int has_focus_proto
= 0;
19 int has_delete_proto
= 1;
22 Atom ATOM_NET_WM_WINDOW_TYPE
= None
;
23 Atom ATOM_NET_WM_WINDOW_TYPE_DESKTOP
= None
;
24 Atom ATOM_NET_WM_WINDOW_TYPE_DOCK
= None
;
25 Atom ATOM_NET_WM_WINDOW_TYPE_TOOLBAR
= None
;
26 Atom ATOM_NET_WM_WINDOW_TYPE_MENU
= None
;
27 Atom ATOM_NET_WM_WINDOW_TYPE_DIALOG
= None
;
28 Atom ATOM_NET_WM_WINDOW_TYPE_NORMAL
= None
;
29 Atom ATOM_NET_WM_WINDOW_TYPE_SPLASH
= None
;
30 Atom ATOM_NET_WM_WINDOW_TYPE_UTILITY
= None
;
31 Atom ATOM_KDE_NET_WM_WINDOW_TYPE_OVERRIDE
= None
;
33 Atom ATOM_NET_WM_STATE
= None
;
34 Atom ATOM_NET_WM_STATE_MODAL
= None
;
35 Atom ATOM_NET_WM_STATE_STICKY
= None
;
36 Atom ATOM_NET_WM_STATE_MAXIMIZED_VERT
= None
;
37 Atom ATOM_NET_WM_STATE_MAXIMIZED_HORIZ
= None
;
38 Atom ATOM_NET_WM_STATE_SHADED
= None
;
39 Atom ATOM_NET_WM_STATE_SKIP_TASKBAR
= None
;
40 Atom ATOM_NET_WM_STATE_SKIP_PAGER
= None
;
41 Atom ATOM_NET_WM_STATE_HIDDEN
= None
;
42 Atom ATOM_NET_WM_STATE_STAYS_ON_TOP
= None
;
43 Atom ATOM_NET_WM_STATE_FULLSCREEN
= None
;
45 Atom ATOM_NET_WM_DESKTOP
= None
;
48 Atom ATOM_WM_DELETE_WINDOW
= None
;
49 Atom ATOM_WM_TAKE_FOCUS
= None
;
51 /* Motif window hints */
52 Atom ATOM_MOTIF_WM_HINTS
= None
;
54 #define MWM_HINTS_FUNCTIONS (1L << 0)
55 #define MWM_HINTS_DECORATIONS (1L << 1)
56 #define MWM_HINTS_INPUT_MODE (1L << 2)
57 #define MWM_HINTS_STATUS (1L << 3) /* ? */
59 /* bit definitions for MwmHints.functions */
60 #define MWM_FUNC_ALL (1L << 0)
61 #define MWM_FUNC_RESIZE (1L << 1)
62 #define MWM_FUNC_MOVE (1L << 2)
63 #define MWM_FUNC_MINIMIZE (1L << 3)
64 #define MWM_FUNC_MAXIMIZE (1L << 4)
65 #define MWM_FUNC_CLOSE (1L << 5)
67 /* values for MwmHints.input_mode */
68 #define MWM_INPUT_MODELESS 0
69 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
70 #define MWM_INPUT_SYSTEM_MODAL 2
71 #define MWM_INPUT_FULL_APPLICATION_MODAL 3
73 /* bit definitions for MwmHints.decorations */
74 #define MWM_DECOR_ALL (1L << 0)
75 #define MWM_DECOR_BORDER (1L << 1)
76 #define MWM_DECOR_RESIZEH (1L << 2)
77 #define MWM_DECOR_TITLE (1L << 3)
78 #define MWM_DECOR_MENU (1L << 4)
79 #define MWM_DECOR_MINIMIZE (1L << 5)
80 #define MWM_DECOR_MAXIMIZE (1L << 6)
89 /* props[1]: functions */
90 /* props[2]: decorations */
91 /* props[3]: inputMode */
94 typedef PropMotifWmHints PropMwmHints
;
96 #define PROP_MOTIF_WM_HINTS_ELEMENTS 4
97 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS
105 XWindowAttributes xatt
;
107 /* Sit and wait for an event to happen */
111 case ConfigureNotify
:
114 if (has_delete_proto
&& ev
.xclient
.format
== 32 &&
115 ev
.xclient
.data
.l
[0] == ATOM_WM_DELETE_WINDOW
)
119 else if (has_focus_proto
&&
120 ev
.xclient
.data
.l
[0] == ATOM_WM_TAKE_FOCUS
)
122 printf("WM_TAKE_FOCUS message\n");
125 printf ("\t...do nothing\n");
127 else if (input_mode
== 0)
129 if (XGetWindowAttributes(dpy
, win
, &xatt
)
130 && xatt
.map_state
== IsViewable
)
132 printf ("\t...setting focus on our own: %lu\n",
133 ev
.xclient
.data
.l
[1]);
135 dpy
, win
, RevertToParent
,
136 ev
.xclient
.data
.l
[1]);
140 printf ("\t...but we are not viewable\n");
151 #define XIA(a) XInternAtom(dpy,a,False);
154 ATOM_NET_WM_WINDOW_TYPE
= XIA("_NET_WM_WINDOW_TYPE");
155 ATOM_NET_WM_WINDOW_TYPE_DESKTOP
= XIA("_NET_WM_WINDOW_TYPE_DESKTOP");
156 ATOM_NET_WM_WINDOW_TYPE_DOCK
= XIA("_NET_WM_WINDOW_TYPE_DOCK");
157 ATOM_NET_WM_WINDOW_TYPE_TOOLBAR
= XIA("_NET_WM_WINDOW_TYPE_TOOLBAR");
158 ATOM_NET_WM_WINDOW_TYPE_MENU
= XIA("_NET_WM_WINDOW_TYPE_MENU");
159 ATOM_NET_WM_WINDOW_TYPE_DIALOG
= XIA("_NET_WM_WINDOW_TYPE_DIALOG");
160 ATOM_NET_WM_WINDOW_TYPE_NORMAL
= XIA("_NET_WM_WINDOW_TYPE_NORMAL");
161 ATOM_NET_WM_WINDOW_TYPE_SPLASH
= XIA("_NET_WM_WINDOW_TYPE_SPLASH");
162 ATOM_NET_WM_WINDOW_TYPE_UTILITY
= XIA("_NET_WM_WINDOW_TYPE_UTILITY");
163 ATOM_KDE_NET_WM_WINDOW_TYPE_OVERRIDE
= XIA("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
165 ATOM_NET_WM_STATE
= XIA("_NET_WM_STATE");
166 ATOM_NET_WM_STATE_MODAL
= XIA("_NET_WM_STATE_MODAL");
167 ATOM_NET_WM_STATE_STICKY
= XIA("_NET_WM_STATE_STICKY");
168 ATOM_NET_WM_STATE_MAXIMIZED_VERT
= XIA("_NET_WM_STATE_MAXIMIZED_VERT");
169 ATOM_NET_WM_STATE_MAXIMIZED_HORIZ
= XIA("_NET_WM_STATE_MAXIMIZED_HORIZ");
170 ATOM_NET_WM_STATE_SHADED
= XIA("_NET_WM_STATE_SHADED");
171 ATOM_NET_WM_STATE_SKIP_TASKBAR
= XIA("_NET_WM_STATE_SKIP_TASKBAR");
172 ATOM_NET_WM_STATE_SKIP_PAGER
= XIA("_NET_WM_STATE_SKIP_PAGER");
173 ATOM_NET_WM_STATE_HIDDEN
= XIA("_NET_WM_STATE_HIDDEN");
174 ATOM_NET_WM_STATE_FULLSCREEN
= XIA("_NET_WM_STATE_FULLSCREEN");
175 ATOM_NET_WM_STATE_STAYS_ON_TOP
= XIA("_NET_WM_STATE_STAYS_ON_TOP");
177 ATOM_NET_WM_DESKTOP
= XIA("_NET_WM_DESKTOP");
179 ATOM_WM_DELETE_WINDOW
= XIA("WM_DELETE_WINDOW");
180 ATOM_WM_TAKE_FOCUS
= XIA("WM_TAKE_FOCUS");
182 ATOM_MOTIF_WM_HINTS
= XIA("_MOTIF_WM_HINTS");
185 void show_usage(void)
187 printf("Usage: hints_test OPTIONS\n");
188 printf("Options:\n");
189 printf(" --mwm-func <names>\n");
190 printf(" all, resize, move, minimize, maximize, close\n");
191 printf(" --mwm-decor <names>\n");
192 printf(" all, border, resizeh, title, menu, minimize, maximize\n");
193 printf(" --ewmh-state <names>\n");
194 printf(" hidden, shaded, sticky, skippager, skiptaskbar,\n");
195 printf(" maxhoriz, maxvert, modal, staysontop, fullscreen\n");
196 printf(" --ewmh-type <names>\n");
197 printf(" normal, dock, toolbar, desktop, menu, dialog, splash, utility\n");
198 printf(" --mwm-input { modless, app_modal, sys_modal, full_app_modal}\n");
199 printf(" --ewmh-desktop\n");
200 printf(" --wm-state { withdrawn, normal, iconic }\n");
201 printf(" --wm-urgency\n");
202 printf(" --wm-group { window, root, <win_id> }\n");
203 printf(" --min-size <width> <height>\n");
204 printf(" --max-size <width> <height>\n");
205 printf(" --inc-size <width> <height>\n");
206 printf(" --p-geometry <geometry>\n");
207 printf(" --us-geometry <geometry>\n");
208 printf(" --input { true, false }\n");
209 printf(" --delete-proto\n");
210 printf(" --no-delete-proto\n");
211 printf(" --transient\n");
214 int main(int argc
, char **argv
)
220 unsigned int h_r
,w_r
;
222 int ewmh_state_arg
= 0;
223 int ewmh_type_arg
= 0;
224 int mwm_func_arg
= 0;
225 int mwm_decor_arg
= 0;
226 int has_ewmh_desktop
= 0;
227 Atom ewmh_desktop
= 0;
229 XClassHint classhints
;
231 PropMwmHints mwm_hints
;
232 Window trans_win
= 0;
234 if (!(dpy
= XOpenDisplay("")))
236 fprintf(stderr
, "can't open display\n");
240 screen
= DefaultScreen(dpy
);
241 Root
= RootWindow(dpy
, screen
);
252 mwm_hints
.props
[0] = 0;
253 mwm_hints
.props
[1] = 0;
254 mwm_hints
.props
[2] = 0;
255 mwm_hints
.props
[3] = 0;
257 win
= XCreateSimpleWindow(
258 dpy
, Root
, 0, 0, hints
.width
, hints
.height
, 0, 0, 0);
260 for (i
= 1; i
< argc
; i
++)
262 char *error_arg
= NULL
;
264 if (strcasecmp(argv
[i
], "--help") == 0)
269 else if (strcasecmp(argv
[i
], "--ewmh-state") == 0)
276 else if (strcasecmp(argv
[i
], "--ewmh-type") == 0)
283 else if (strcasecmp(argv
[i
], "--mwm-func") == 0)
290 else if (strcasecmp(argv
[i
], "--mwm-decor") == 0)
297 else if (strcasecmp(argv
[i
], "--min-size") == 0)
300 hints
.min_width
= atoi(argv
[i
]);
302 hints
.min_height
= atoi(argv
[i
]);
303 hints
.flags
|= PMinSize
;
305 else if (strcasecmp(argv
[i
], "--max-size") == 0)
308 hints
.max_width
= atoi(argv
[i
]);
310 hints
.max_height
= atoi(argv
[i
]);
311 hints
.flags
|= PMaxSize
;
313 else if (strcasecmp(argv
[i
], "--inc-size") == 0)
316 hints
.width_inc
= atoi(argv
[i
]);
318 hints
.height_inc
= atoi(argv
[i
]);
319 hints
.flags
|= PResizeInc
;
321 else if (strcasecmp(argv
[i
], "--p-geometry") == 0)
324 ret
= XParseGeometry(argv
[i
], &x_r
, &y_r
, &w_r
, &h_r
);
325 if ((ret
& WidthValue
) && (ret
& HeightValue
))
329 hints
.flags
|= PSize
;
331 if ((ret
& XValue
) && (ret
& YValue
))
335 hints
.win_gravity
= NorthWestGravity
;
338 hints
.x
+= XDisplayWidth(dpy
, screen
) -
340 hints
.win_gravity
= NorthEastGravity
;
344 hints
.y
+= XDisplayHeight(dpy
, screen
) -
356 hints
.flags
|= PWinGravity
;
358 hints
.flags
|= PPosition
;
361 else if (strcasecmp(argv
[i
], "--us-geometry") == 0)
364 ret
= XParseGeometry(argv
[i
], &x_r
, &y_r
, &w_r
, &h_r
);
365 if ((ret
& WidthValue
) && (ret
& HeightValue
))
369 hints
.flags
|= USSize
;
371 if ((ret
& XValue
) && (ret
& YValue
))
375 hints
.win_gravity
=NorthWestGravity
;
378 hints
.x
+= XDisplayWidth(dpy
,screen
) -
380 hints
.win_gravity
=NorthEastGravity
;
384 hints
.y
+= XDisplayHeight(dpy
,screen
) -
397 hints
.flags
|= USPosition
| PWinGravity
;
400 else if (strcasecmp(argv
[i
], "--input") == 0)
403 if (strcasecmp(argv
[i
], "true") == 0)
405 wm_hints
.input
= input_mode
= True
;
406 wm_hints
.flags
|= InputHint
;
408 else if (strcasecmp(argv
[i
], "false") == 0)
410 wm_hints
.input
= input_mode
= False
;
411 wm_hints
.flags
|= InputHint
;
415 error_arg
= "--input";
418 else if (strcasecmp(argv
[i
], "--focus-proto") == 0)
422 else if (strcasecmp(argv
[i
], "--no-delete-proto") == 0)
424 has_delete_proto
= 0;
426 else if (strcasecmp(argv
[i
], "--wm-state") == 0)
428 wm_hints
.flags
|= StateHint
;
430 if (strcasecmp(argv
[i
], "withdrawn") == 0)
432 wm_hints
.initial_state
= WithdrawnState
;
434 else if (strcasecmp(argv
[i
], "normal") == 0)
436 wm_hints
.initial_state
= NormalState
;
438 else if (strcasecmp(argv
[i
], "iconic") == 0)
440 wm_hints
.initial_state
= IconicState
;
444 error_arg
= "--wm-state";
447 else if (strcasecmp(argv
[i
], "--wm-urgency") == 0)
449 wm_hints
.flags
|= XUrgencyHint
;
451 else if (strcasecmp(argv
[i
], "--wm-group") == 0)
453 wm_hints
.flags
|= WindowGroupHint
;
455 if (strcasecmp(argv
[i
], "window") == 0)
457 wm_hints
.window_group
= win
;
459 else if (strcasecmp(argv
[i
], "root") == 0)
461 wm_hints
.window_group
= Root
;
465 wm_hints
.window_group
=
466 strtoul(argv
[i
], NULL
, 0);
469 else if (strcasecmp(argv
[i
], "--transient") == 0)
472 if (strcasecmp(argv
[i
],"root") == 0)
478 trans_win
= strtoul(argv
[i
], NULL
, 0);
481 else if (strcasecmp(argv
[i
], "--mwm-input") == 0)
483 mwm_hints
.props
[0] |= MWM_HINTS_INPUT_MODE
;
485 if (strcasecmp(argv
[i
], "modless") == 0)
487 mwm_hints
.props
[3] = MWM_INPUT_MODELESS
;
489 else if (strcasecmp(argv
[i
], "app_modal") == 0)
492 MWM_INPUT_PRIMARY_APPLICATION_MODAL
;
494 else if (strcasecmp(argv
[i
], "sys_modal") == 0)
497 MWM_INPUT_SYSTEM_MODAL
;
499 else if (strcasecmp(argv
[i
], "full_app_modal") == 0)
502 MWM_INPUT_FULL_APPLICATION_MODAL
;
506 error_arg
= "--mwm-input";
509 else if (strcasecmp(argv
[i
], "--ewmh-desktop") == 0)
511 has_ewmh_desktop
= 1;
513 ewmh_desktop
= atol(argv
[i
]);
515 else if (ewmh_state_arg
&& state_count
< 10)
517 if (strcasecmp(argv
[i
], "hidden") == 0)
519 states
[state_count
++] =
520 ATOM_NET_WM_STATE_HIDDEN
;
522 else if (strcasecmp(argv
[i
], "shaded") == 0)
524 states
[state_count
++] =
525 ATOM_NET_WM_STATE_SHADED
;
527 else if (strcasecmp(argv
[i
], "sticky") == 0)
529 states
[state_count
++] =
530 ATOM_NET_WM_STATE_STICKY
;
532 else if (strcasecmp(argv
[i
], "skippager") == 0)
534 states
[state_count
++] =
535 ATOM_NET_WM_STATE_SKIP_PAGER
;
537 else if (strcasecmp(argv
[i
], "skiptaskbar") == 0)
539 states
[state_count
++] =
540 ATOM_NET_WM_STATE_SKIP_TASKBAR
;
542 else if (strcasecmp(argv
[i
], "maxhoriz") == 0)
544 states
[state_count
++] =
545 ATOM_NET_WM_STATE_MAXIMIZED_HORIZ
;
547 else if (strcasecmp(argv
[i
], "maxvert") == 0)
549 states
[state_count
++] =
550 ATOM_NET_WM_STATE_MAXIMIZED_VERT
;
552 else if (strcasecmp(argv
[i
], "modal") == 0)
554 states
[state_count
++] =
555 ATOM_NET_WM_STATE_MODAL
;
557 else if (strcasecmp(argv
[i
], "staysontop") == 0)
559 states
[state_count
++] =
560 ATOM_NET_WM_STATE_STAYS_ON_TOP
;
562 else if (strcasecmp(argv
[i
], "fullscreen") == 0)
564 states
[state_count
++] =
565 ATOM_NET_WM_STATE_FULLSCREEN
;
569 error_arg
= "--ewmh-state";
572 else if (ewmh_type_arg
)
574 if (strcasecmp(argv
[i
], "normal") == 0)
576 type
= ATOM_NET_WM_WINDOW_TYPE_NORMAL
;
578 else if (strcasecmp(argv
[i
], "dock") == 0)
580 type
= ATOM_NET_WM_WINDOW_TYPE_DOCK
;
582 else if (strcasecmp(argv
[i
], "toolbar") == 0)
584 type
= ATOM_NET_WM_WINDOW_TYPE_TOOLBAR
;
586 else if (strcasecmp(argv
[i
], "desktop") == 0)
588 type
= ATOM_NET_WM_WINDOW_TYPE_DESKTOP
;
590 else if (strcasecmp(argv
[i
], "menu") == 0)
592 type
= ATOM_NET_WM_WINDOW_TYPE_MENU
;
594 else if (strcasecmp(argv
[i
], "dialog") == 0)
596 type
= ATOM_NET_WM_WINDOW_TYPE_DIALOG
;
598 else if (strcasecmp(argv
[i
], "splash") == 0)
600 type
= ATOM_NET_WM_WINDOW_TYPE_SPLASH
;
602 else if (strcasecmp(argv
[i
], "utility") == 0)
604 type
= ATOM_NET_WM_WINDOW_TYPE_UTILITY
;
608 error_arg
= "--ewmh-type";
611 else if (mwm_func_arg
)
613 mwm_hints
.props
[0] |= MWM_HINTS_FUNCTIONS
;
614 if (strcasecmp(argv
[i
], "all") == 0)
616 mwm_hints
.props
[1] |= MWM_FUNC_ALL
;
618 else if (strcasecmp(argv
[i
], "resize") == 0)
620 mwm_hints
.props
[1] |= MWM_FUNC_RESIZE
;
622 else if (strcasecmp(argv
[i
], "move") == 0)
624 mwm_hints
.props
[1] |= MWM_FUNC_MOVE
;
626 else if (strcasecmp(argv
[i
], "minimize") == 0)
628 mwm_hints
.props
[1] |= MWM_FUNC_MINIMIZE
;
630 else if (strcasecmp(argv
[i
], "maximize") == 0)
632 mwm_hints
.props
[1] |= MWM_FUNC_MAXIMIZE
;
634 else if (strcasecmp(argv
[i
], "close") == 0)
636 mwm_hints
.props
[1] |= MWM_FUNC_CLOSE
;
640 error_arg
= "--mwm-func";
643 else if (mwm_decor_arg
)
645 mwm_hints
.props
[0] |= MWM_HINTS_DECORATIONS
;
646 if (strcasecmp(argv
[i
], "all") == 0)
648 mwm_hints
.props
[2] |= MWM_DECOR_ALL
;
650 else if (strcasecmp(argv
[i
], "border") == 0)
652 mwm_hints
.props
[2] |= MWM_DECOR_BORDER
;
654 else if (strcasecmp(argv
[i
], "resizeh") == 0)
656 mwm_hints
.props
[2] |= MWM_DECOR_RESIZEH
;
658 else if (strcasecmp(argv
[i
], "title") == 0)
660 mwm_hints
.props
[2] |= MWM_DECOR_TITLE
;
662 else if (strcasecmp(argv
[i
], "menu") == 0)
664 mwm_hints
.props
[2] |= MWM_DECOR_MENU
;
666 else if (strcasecmp(argv
[i
], "minimize") == 0)
668 mwm_hints
.props
[2] |= MWM_DECOR_MINIMIZE
;
670 else if (strcasecmp(argv
[i
], "maximize") == 0)
672 mwm_hints
.props
[2] |= MWM_DECOR_MAXIMIZE
;
676 error_arg
= "--mwm-decor";
681 error_arg
= "regular";
686 printf("Invalid %s argument: %s\n", error_arg
, argv
[i
]);
692 XSelectInput(dpy
, win
, StructureNotifyMask
);
696 XSetWMHints(dpy
, win
, &wm_hints
);
699 if (state_count
!= 0)
702 dpy
, win
, ATOM_NET_WM_STATE
, XA_ATOM
, 32,
703 PropModeReplace
, (unsigned char *)states
, state_count
);
709 dpy
, win
, ATOM_NET_WM_WINDOW_TYPE
, XA_ATOM
, 32,
710 PropModeReplace
, (unsigned char *)&type
, 1);
713 if (has_ewmh_desktop
)
716 dpy
, win
, ATOM_NET_WM_DESKTOP
, XA_CARDINAL
, 32,
717 PropModeReplace
, (unsigned char *)&ewmh_desktop
, 1);
720 if (has_delete_proto
|| has_focus_proto
)
725 if (has_delete_proto
)
726 proto
[j
++] = ATOM_WM_DELETE_WINDOW
;
728 proto
[j
++] = ATOM_WM_TAKE_FOCUS
;
730 XSetWMProtocols(dpy
, win
, proto
, j
);
734 XTextProperty nametext
;
735 char *list
[] = { NULL
, NULL
};
736 list
[0] = "Hints Test";
738 classhints
.res_name
= strdup("hints_test");
739 classhints
.res_class
= strdup("HintsTest");
741 if (!XStringListToTextProperty(list
, 1, &nametext
))
743 fprintf(stderr
, "Failed to convert name to XText\n");
747 dpy
, win
, &nametext
, &nametext
, NULL
, 0, &hints
, NULL
,
749 XFree(nametext
.value
);
752 if (mwm_hints
.props
[0] != 0)
755 dpy
, win
, ATOM_MOTIF_WM_HINTS
, ATOM_MOTIF_WM_HINTS
, 32,
756 PropModeReplace
,(unsigned char *)&mwm_hints
,
757 PROP_MWM_HINTS_ELEMENTS
);
760 XSetTransientForHint(dpy
, win
, trans_win
);
762 XMapWindow(dpy
, win
);
763 XSetWindowBackground(dpy
, win
, 0);