static void place_per_app_setting_size(ObClient *client, Rect *screen, gint *w, gint *h, ObAppSettings *settings) { if (!settings) return; g_assert(settings->width_num >= 0); g_assert(settings->width_denom >= 0); g_assert(settings->height_num >= 0); g_assert(settings->height_denom >= 0); if (settings->width_num) { ob_debug("setting width by per-app settings"); if (!settings->width_denom) *w = settings->width_num; else { *w = screen->width * settings->width_num / settings->width_denom; *w = MIN(*w, screen->width); } } if (settings->height_num) { ob_debug("setting height by per-app settings"); if (!settings->height_denom) *h = settings->height_num; else { *h = screen->height * settings->height_num / settings->height_denom; *h = MIN(*h, screen->height); } } }
void window_manage(Window win) { XWindowAttributes attrib; gboolean no_manage = FALSE; gboolean is_dockapp = FALSE; Window icon_win = None; grab_server(TRUE); /* check if it has already been unmapped by the time we started mapping. the grab does a sync so we don't have to here */ if (xqueue_exists_local(check_unmap, &win)) { ob_debug("Trying to manage unmapped window. Aborting that."); no_manage = TRUE; } else if (!XGetWindowAttributes(obt_display, win, &attrib)) no_manage = TRUE; else { XWMHints *wmhints; /* is the window a docking app */ is_dockapp = FALSE; if ((wmhints = XGetWMHints(obt_display, win))) { if ((wmhints->flags & StateHint) && wmhints->initial_state == WithdrawnState) { if (wmhints->flags & IconWindowHint) icon_win = wmhints->icon_window; is_dockapp = TRUE; } XFree(wmhints); } } if (!no_manage) { if (attrib.override_redirect) { ob_debug("not managing override redirect window 0x%x", win); grab_server(FALSE); } else if (is_dockapp) { if (!icon_win) icon_win = win; dock_manage(icon_win, win); } else client_manage(win, NULL); } else { grab_server(FALSE); ob_debug("FAILED to manage window 0x%x", win); } }
static gboolean place_per_app_setting_position(ObClient *client, Rect *screen, gint *x, gint *y, ObAppSettings *settings, Size frame_size) { if (!settings || !settings->pos_given) return FALSE; ob_debug("placing by per-app settings"); if (settings->position.x.center) *x = screen->x + screen->width / 2 - client->area.width / 2; else if (settings->position.x.opposite) *x = screen->x + screen->width - frame_size.width - settings->position.x.pos; else *x = screen->x + settings->position.x.pos; if (settings->position.x.denom) *x = (*x * screen->width) / settings->position.x.denom; if (settings->position.y.center) *y = screen->y + screen->height / 2 - client->area.height / 2; else if (settings->position.y.opposite) *y = screen->y + screen->height - frame_size.height - settings->position.y.pos; else *y = screen->y + settings->position.y.pos; if (settings->position.y.denom) *y = (*y * screen->height) / settings->position.y.denom; return TRUE; }
static gboolean place_under_mouse(ObClient *client, gint *x, gint *y, Size frame_size) { if (config_place_policy != OB_PLACE_POLICY_MOUSE) return FALSE; gint l, r, t, b; gint px, py; Rect *area; ob_debug("placing under mouse"); if (!screen_pointer_pos(&px, &py)) return FALSE; area = choose_pointer_monitor(client); l = area->x; t = area->y; r = area->x + area->width - frame_size.width; b = area->y + area->height - frame_size.height; *x = px - frame_size.width / 2; *x = MIN(MAX(*x, l), r); *y = py - frame_size.height / 2; *y = MIN(MAX(*y, t), b); g_slice_free(Rect, area); return TRUE; }
/*! Connect to the session manager and set up our callback functions */ static gboolean session_connect(void) { SmcCallbacks cb; gchar *oldid; gchar sm_err[SM_ERR_LEN]; /* set up our callback functions */ cb.save_yourself.callback = sm_save_yourself; cb.save_yourself.client_data = NULL; cb.die.callback = sm_die; cb.die.client_data = NULL; cb.save_complete.callback = sm_save_complete; cb.save_complete.client_data = NULL; cb.shutdown_cancelled.callback = sm_shutdown_cancelled; cb.shutdown_cancelled.client_data = NULL; /* connect to the server */ oldid = ob_sm_id; ob_debug_type(OB_DEBUG_SM, "Connecting to SM with id: %s", oldid ? oldid : "(null)"); sm_conn = SmcOpenConnection(NULL, NULL, 1, 0, SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, &cb, oldid, &ob_sm_id, SM_ERR_LEN-1, sm_err); g_free(oldid); ob_debug_type(OB_DEBUG_SM, "Connected to SM with id: %s", ob_sm_id); if (sm_conn == NULL) ob_debug("Failed to connect to session manager: %s", sm_err); return sm_conn != NULL; }
static gboolean place_transient_splash(ObClient *client, Rect *area, gint *x, gint *y, Size frame_size) { if (client->type == OB_CLIENT_TYPE_DIALOG) { GSList *it; gboolean first = TRUE; gint l, r, t, b; ob_debug("placing dialog"); for (it = client->parents; it; it = g_slist_next(it)) { ObClient *m = it->data; if (!m->iconic) { if (first) { l = RECT_LEFT(m->frame->area); t = RECT_TOP(m->frame->area); r = RECT_RIGHT(m->frame->area); b = RECT_BOTTOM(m->frame->area); first = FALSE; } else { l = MIN(l, RECT_LEFT(m->frame->area)); t = MIN(t, RECT_TOP(m->frame->area)); r = MAX(r, RECT_RIGHT(m->frame->area)); b = MAX(b, RECT_BOTTOM(m->frame->area)); } } if (!first) { *x = ((r + 1 - l) - frame_size.width) / 2 + l; *y = ((b + 1 - t) - frame_size.height) / 2 + t; return TRUE; } } } if (client->type == OB_CLIENT_TYPE_DIALOG || client->type == OB_CLIENT_TYPE_SPLASH) { ob_debug("placing dialog or splash"); *x = (area->width - frame_size.width) / 2 + area->x; *y = (area->height - frame_size.height) / 2 + area->y; return TRUE; } return FALSE; }
void grab_key(guint keycode, guint state, Window win, gint keyboard_mode) { guint i; xerror_set_ignore(TRUE); /* can get BadAccess' from these */ xerror_occured = FALSE; for (i = 0; i < MASK_LIST_SIZE; ++i) XGrabKey(ob_display, keycode, state | mask_list[i], win, FALSE, GrabModeAsync, keyboard_mode); xerror_set_ignore(FALSE); if (xerror_occured) ob_debug("Failed to grab keycode %d modifiers %d\n", keycode, state); }
void grab_button_full(guint button, guint state, Window win, guint mask, gint pointer_mode, ObCursor cur) { guint i; xerror_set_ignore(TRUE); /* can get BadAccess from these */ xerror_occured = FALSE; for (i = 0; i < MASK_LIST_SIZE; ++i) XGrabButton(ob_display, button, state | mask_list[i], win, False, mask, pointer_mode, GrabModeAsync, None, ob_cursor(cur)); xerror_set_ignore(FALSE); if (xerror_occured) ob_debug("Failed to grab button %d modifiers %d\n", button, state); }
void window_manage_all(void) { guint i, j, nchild; Window w, *children; XWMHints *wmhints; XWindowAttributes attrib; if (!XQueryTree(obt_display, RootWindow(obt_display, ob_screen), &w, &w, &children, &nchild)) { ob_debug("XQueryTree failed in window_manage_all"); nchild = 0; } /* remove all icon windows from the list */ for (i = 0; i < nchild; i++) { if (children[i] == None) continue; wmhints = XGetWMHints(obt_display, children[i]); if (wmhints) { if ((wmhints->flags & IconWindowHint) && (wmhints->icon_window != children[i])) for (j = 0; j < nchild; j++) if (children[j] == wmhints->icon_window) { /* XXX watch the window though */ children[j] = None; break; } XFree(wmhints); } } for (i = 0; i < nchild; ++i) { if (children[i] == None) continue; if (window_find(children[i])) continue; /* skip our own windows */ if (XGetWindowAttributes(obt_display, children[i], &attrib)) { if (attrib.map_state == IsUnmapped) ; else window_manage(children[i]); } } if (children) XFree(children); }
/*! Pick a monitor to place a window on. */ static Rect* choose_monitor(ObClient *c, gboolean client_to_be_foregrounded, ObAppSettings *settings) { Rect *area; ObPlaceHead *choice; guint i; ObClient *p; GSList *it; choice = g_new(ObPlaceHead, screen_num_monitors); for (i = 0; i < screen_num_monitors; ++i) { choice[i].monitor = i; choice[i].flags = 0; } /* find monitors with group members */ if (c->group) { for (it = c->group->members; it; it = g_slist_next(it)) { ObClient *itc = it->data; if (itc != c) { guint m = client_monitor(itc); if (m < screen_num_monitors) { if (screen_compare_desktops(itc->desktop, c->desktop)) choice[m].flags |= HEAD_GROUP_DESK; else choice[m].flags |= HEAD_GROUP; } } } } i = screen_monitor_primary(FALSE); if (i < screen_num_monitors) { choice[i].flags |= HEAD_PRIMARY; if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY) choice[i].flags |= HEAD_PLACED; if (settings && settings->monitor_type == OB_PLACE_MONITOR_PRIMARY) choice[i].flags |= HEAD_PERAPP; } i = screen_monitor_active(); if (i < screen_num_monitors) { if (config_place_monitor == OB_PLACE_MONITOR_ACTIVE) choice[i].flags |= HEAD_PLACED; if (settings && settings->monitor_type == OB_PLACE_MONITOR_ACTIVE) choice[i].flags |= HEAD_PERAPP; } i = screen_monitor_pointer(); if (i < screen_num_monitors) { if (config_place_monitor == OB_PLACE_MONITOR_MOUSE) choice[i].flags |= HEAD_PLACED; if (settings && settings->monitor_type == OB_PLACE_MONITOR_MOUSE) choice[i].flags |= HEAD_PERAPP; } if (settings) { i = settings->monitor - 1; if (i < screen_num_monitors) choice[i].flags |= HEAD_PERAPP; } /* direct parent takes highest precedence */ if ((p = client_direct_parent(c))) { i = client_monitor(p); if (i < screen_num_monitors) choice[i].flags |= HEAD_PARENT; } qsort(choice, screen_num_monitors, sizeof(ObPlaceHead), client_to_be_foregrounded ? cmp_foreground : cmp_background); /* save the areas of the monitors in order of their being chosen */ for (i = 0; i < screen_num_monitors; ++i) { ob_debug("placement choice %d is monitor %d", i, choice[i].monitor); if (choice[i].flags & HEAD_PARENT) ob_debug(" - parent on monitor"); if (choice[i].flags & HEAD_PLACED) ob_debug(" - placement choice"); if (choice[i].flags & HEAD_PRIMARY) ob_debug(" - primary monitor"); if (choice[i].flags & HEAD_GROUP_DESK) ob_debug(" - group on same desktop"); if (choice[i].flags & HEAD_GROUP) ob_debug(" - group on other desktop"); } area = screen_area(c->desktop, choice[0].monitor, NULL); g_free(choice); /* return the area for the chosen monitor */ return area; }