+ if (dir == 0 || dir == 1) /* horz */
+ self->max_horz = max;
+ if (dir == 0 || dir == 2) /* vert */
+ self->max_vert = max;
+
+ client_change_state(self); /* change the state hints on the client */
+
+ client_setup_decor_and_functions(self, FALSE);
+ client_move_resize(self, x, y, w, h);
+}
+
+void client_shade(ObClient *self, gboolean shade)
+{
+ if ((!(self->functions & OB_CLIENT_FUNC_SHADE) &&
+ shade) || /* can't shade */
+ self->shaded == shade) return; /* already done */
+
+ self->shaded = shade;
+ client_change_state(self);
+ client_change_wm_state(self); /* the window is being hidden/shown */
+ /* resize the frame to just the titlebar */
+ frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
+}
+
+static void client_ping_event(ObClient *self, gboolean dead)
+{
+ if (self->not_responding != dead) {
+ self->not_responding = dead;
+ client_update_title(self);
+
+ if (dead)
+ /* the client isn't responding, so ask to kill it */
+ client_prompt_kill(self);
+ else {
+ /* it came back to life ! */
+
+ if (self->kill_prompt) {
+ prompt_unref(self->kill_prompt);
+ self->kill_prompt = NULL;
+ }
+
+ self->kill_level = 0;
+ }
+ }
+}
+
+void client_close(ObClient *self)
+{
+ if (!(self->functions & OB_CLIENT_FUNC_CLOSE)) return;
+
+ /* if closing an internal obprompt, that is just cancelling it */
+ if (self->prompt) {
+ prompt_cancel(self->prompt);
+ return;
+ }
+
+ /* in the case that the client provides no means to requesting that it
+ close, we just kill it */
+ if (!self->delete_window)
+ /* don't use client_kill(), we should only kill based on PID in
+ response to a lack of PING replies */
+ XKillClient(ob_display, self->window);
+ else {
+ /* request the client to close with WM_DELETE_WINDOW */
+ PROP_MSG_TO(self->window, self->window, wm_protocols,
+ prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
+ NoEventMask);
+
+ /* we're trying to close the window, so see if it is responding. if it
+ is not, then we will let them kill the window */
+ if (self->ping)
+ ping_start(self, client_ping_event);
+
+ /* if we already know the window isn't responding (maybe they clicked
+ no in the kill dialog but it hasn't come back to life), then show
+ the kill dialog */
+ if (self->not_responding)
+ client_prompt_kill(self);
+ }
+}
+
+#define OB_KILL_RESULT_NO 0
+#define OB_KILL_RESULT_YES 1