X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=0389d768025e7fe5a45eff9e95e81fa9b4a8782f;hb=140c5313cfe38aada8bd15892f74fc0d21d374c1;hp=457a0f6ad03e2292406335d7d49d552b20cf5fb2;hpb=96eab1423fbb92bfe35dc1cad0e43a90b9f1bc21;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 457a0f6a..0389d768 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -218,10 +218,11 @@ static ObAppSettings *get_settings(ObClient *client) && !strcmp(app->name, client->name)) ) { ob_debug("Window matching: %s\n", app->name); - /* Match if no role was specified in the per app setting, or if the string - * matches the beginning of the role, since apps like to set the role to - * things like browser-window-23c4b2f */ - if (!app->role || !strncmp(app->role, client->role, strlen(app->role))) + /* Match if no role was specified in the per app setting, or if the + * string matches the beginning of the role, since apps like to set + * the role to things like browser-window-23c4b2f */ + if (!app->role + || !strncmp(app->role, client->role, strlen(app->role))) return app; } @@ -311,7 +312,7 @@ void client_manage(Window window) XChangeSaveSet(ob_display, window, SetModeInsert); /* create the decoration frame for the client window */ - self->frame = frame_new(); + self->frame = frame_new(self); frame_grab_client(self->frame, self); @@ -370,8 +371,9 @@ void client_manage(Window window) /* focus the new window? */ if (ob_state() != OB_STATE_STARTING && - (config_focus_new || client_search_focus_parent(self)) || - (settings && settings->focus == TRUE) && + ((settings && settings->focus == TRUE) || + (!settings && (config_focus_new || + client_search_focus_parent(self)))) && /* note the check against Type_Normal/Dialog, not client_normal(self), which would also include other types. in this case we want more strict rules for focus */ @@ -474,7 +476,8 @@ void client_manage(Window window) g_hash_table_insert(window_map, &self->window, self); /* this has to happen after we're in the client_list */ - screen_update_areas(); + if (STRUT_EXISTS(self->strut)) + screen_update_areas(); /* update the list hints */ client_set_list(); @@ -521,7 +524,8 @@ void client_unmanage(ObClient *self) /* once the client is out of the list, update the struts to remove it's influence */ - screen_update_areas(); + if (STRUT_EXISTS(self->strut)) + screen_update_areas(); for (it = client_destructors; it; it = g_slist_next(it)) { Destructor *d = it->data; @@ -809,19 +813,21 @@ static void client_toggle_border(ObClient *self, gboolean show) static void client_get_all(ObClient *self) { client_get_area(self); - client_update_transient_for(self); - client_update_wmhints(self); - client_get_startup_id(self); - client_get_desktop(self); - client_get_shaped(self); - client_get_mwm_hints(self); - client_get_type(self);/* this can change the mwmhints for special cases */ /* The transient hint is used to pick a type, but the type can also affect - transiency (dialogs are always made transients). This is Havoc's idea, - but it is needed to make some apps work right (eg tsclient). */ + transiency (dialogs are always made transients of their group if they + have one). This is Havoc's idea, but it is needed to make some apps + work right (eg tsclient). */ client_update_transient_for(self); + client_get_type(self);/* this can change the mwmhints for special cases */ + client_update_transient_for(self); + + client_update_wmhints(self); + client_get_startup_id(self); + client_get_desktop(self);/* uses transient data/group/startup id if a + desktop is not specified */ + client_get_shaped(self); client_get_state(self); @@ -1302,10 +1308,15 @@ void client_setup_decor_and_functions(ObClient *self) if (! (self->mwmhints.decorations & OB_MWM_DECOR_ALL)) { if (! ((self->mwmhints.decorations & OB_MWM_DECOR_HANDLE) || (self->mwmhints.decorations & OB_MWM_DECOR_TITLE))) + { /* if the mwm hints request no handle or title, then all - decorations are disabled */ - self->decorations = config_theme_keepborder ? - self->decorations & OB_FRAME_DECOR_BORDER : 0; + decorations are disabled, but keep the border if that's + specified */ + if (self->mwmhints.decorations & OB_MWM_DECOR_BORDER) + self->decorations = OB_FRAME_DECOR_BORDER; + else + self->decorations = 0; + } } } @@ -2345,7 +2356,8 @@ static void client_iconify_recursive(ObClient *self, if (changed) { client_change_state(self); client_showhide(self); - screen_update_areas(); + if (STRUT_EXISTS(self->strut)) + screen_update_areas(); } /* iconify all transients */ @@ -2493,7 +2505,7 @@ void client_close(ObClient *self) ce.xclient.window = self->window; ce.xclient.format = 32; ce.xclient.data.l[0] = prop_atoms.wm_delete_window; - ce.xclient.data.l[1] = event_lasttime; + ce.xclient.data.l[1] = event_curtime; ce.xclient.data.l[2] = 0l; ce.xclient.data.l[3] = 0l; ce.xclient.data.l[4] = 0l; @@ -2531,7 +2543,8 @@ void client_set_desktop_recursive(ObClient *self, /* raise if it was not already on the desktop */ if (old != DESKTOP_ALL) client_raise(self); - screen_update_areas(); + if (STRUT_EXISTS(self->strut)) + screen_update_areas(); /* add to the new desktop(s) */ if (config_focus_new) @@ -2814,7 +2827,7 @@ gboolean client_focus(ObClient *self) #799. So now it is RevertToNone again. */ XSetInputFocus(ob_display, self->window, RevertToNone, - event_lasttime); + event_curtime); } if (self->focus_notify) { @@ -2825,7 +2838,7 @@ gboolean client_focus(ObClient *self) ce.xclient.window = self->window; ce.xclient.format = 32; ce.xclient.data.l[0] = prop_atoms.wm_take_focus; - ce.xclient.data.l[1] = event_lasttime; + ce.xclient.data.l[1] = event_curtime; ce.xclient.data.l[2] = 0l; ce.xclient.data.l[3] = 0l; ce.xclient.data.l[4] = 0l; @@ -2835,7 +2848,7 @@ gboolean client_focus(ObClient *self) #ifdef DEBUG_FOCUS ob_debug("%sively focusing %lx at %d\n", (self->can_focus ? "act" : "pass"), - self->window, (gint) event_lasttime); + self->window, (gint) event_curtime); #endif /* Cause the FocusIn to come back to us. Important for desktop switches, @@ -2857,8 +2870,11 @@ void client_unfocus(ObClient *self) } } -void client_activate(ObClient *self, gboolean here) +void client_activate(ObClient *self, gboolean here, gboolean user) { + /* XXX do some stuff here if user is false to determine if we really want + to activate it or not (a parent or group member is currently active) */ + if (client_normal(self) && screen_showing_desktop) screen_show_desktop(FALSE); if (self->iconic) @@ -2993,8 +3009,8 @@ ObClient *client_find_directional(ObClient *c, ObDirection dir) continue; if(cur->iconic) continue; - if(client_focus_target(cur) == cur && - !(cur->can_focus || cur->focus_notify)) + if(!(client_focus_target(cur) == cur && + client_can_focus(cur))) continue; /* find the centre coords of this window, from the @@ -3213,11 +3229,30 @@ void client_update_sm_client_id(ObClient *self) &self->sm_client_id); } +#define WANT_EDGE(cur, c) \ + if(cur == c) \ + continue; \ + if(!client_normal(cur)) \ + continue; \ + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) \ + continue; \ + if(cur->iconic) \ + continue; \ + if(cur->layer < c->layer && !config_resist_layers_below) \ + continue; + +#define HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) \ + if ((his_edge_start >= my_edge_start && \ + his_edge_start <= my_edge_end) || \ + (my_edge_start >= his_edge_start && \ + my_edge_start <= his_edge_end)) \ + dest = his_offset; + /* finds the nearest edge in the given direction from the current client * note to self: the edge is the -frame- edge (the actual one), not the * client edge. */ -gint client_directional_edge_search(ObClient *c, ObDirection dir) +gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang) { gint dest, monitor_dest; gint my_edge_start, my_edge_end, my_offset; @@ -3234,11 +3269,11 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) case OB_DIRECTION_NORTH: my_edge_start = c->frame->area.x; my_edge_end = c->frame->area.x + c->frame->area.width; - my_offset = c->frame->area.y; + my_offset = c->frame->area.y + (hang ? c->frame->area.height : 0); /* default: top of screen */ - dest = a->y; - monitor_dest = monitor->y; + dest = a->y + (hang ? c->frame->area.height : 0); + monitor_dest = monitor->y + (hang ? c->frame->area.height : 0); /* if the monitor edge comes before the screen edge, */ /* use that as the destination instead. (For xinerama) */ if (monitor_dest != dest && my_offset > monitor_dest) @@ -3248,45 +3283,31 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; - if(cur == c) - continue; - if(!client_normal(cur)) - continue; - if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) - continue; - if(cur->iconic) - continue; - if(cur->layer < c->layer && !config_resist_layers_below) - continue; + WANT_EDGE(cur, c) his_edge_start = cur->frame->area.x; his_edge_end = cur->frame->area.x + cur->frame->area.width; - his_offset = cur->frame->area.y + cur->frame->area.height; + his_offset = cur->frame->area.y + + (hang ? 0 : cur->frame->area.height); if(his_offset + 1 > my_offset) continue; if(his_offset < dest) continue; - - if(his_edge_start >= my_edge_start && - his_edge_start <= my_edge_end) - dest = his_offset; - - if(my_edge_start >= his_edge_start && - my_edge_start <= his_edge_end) - dest = his_offset; + HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) } break; case OB_DIRECTION_SOUTH: my_edge_start = c->frame->area.x; my_edge_end = c->frame->area.x + c->frame->area.width; - my_offset = c->frame->area.y + c->frame->area.height; + my_offset = c->frame->area.y + (hang ? 0 : c->frame->area.height); /* default: bottom of screen */ - dest = a->y + a->height; - monitor_dest = monitor->y + monitor->height; + dest = a->y + a->height - (hang ? c->frame->area.height : 0); + monitor_dest = monitor->y + monitor->height - + (hang ? c->frame->area.height : 0); /* if the monitor edge comes before the screen edge, */ /* use that as the destination instead. (For xinerama) */ if (monitor_dest != dest && my_offset < monitor_dest) @@ -3296,20 +3317,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; - if(cur == c) - continue; - if(!client_normal(cur)) - continue; - if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) - continue; - if(cur->iconic) - continue; - if(cur->layer < c->layer && !config_resist_layers_below) - continue; + WANT_EDGE(cur, c) his_edge_start = cur->frame->area.x; his_edge_end = cur->frame->area.x + cur->frame->area.width; - his_offset = cur->frame->area.y; + his_offset = cur->frame->area.y + + (hang ? cur->frame->area.height : 0); if(his_offset - 1 < my_offset) @@ -3317,25 +3330,18 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) if(his_offset > dest) continue; - - if(his_edge_start >= my_edge_start && - his_edge_start <= my_edge_end) - dest = his_offset; - - if(my_edge_start >= his_edge_start && - my_edge_start <= his_edge_end) - dest = his_offset; + HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) } break; case OB_DIRECTION_WEST: my_edge_start = c->frame->area.y; my_edge_end = c->frame->area.y + c->frame->area.height; - my_offset = c->frame->area.x; + my_offset = c->frame->area.x + (hang ? c->frame->area.width : 0); /* default: leftmost egde of screen */ - dest = a->x; - monitor_dest = monitor->x; + dest = a->x + (hang ? c->frame->area.width : 0); + monitor_dest = monitor->x + (hang ? c->frame->area.width : 0); /* if the monitor edge comes before the screen edge, */ /* use that as the destination instead. (For xinerama) */ if (monitor_dest != dest && my_offset > monitor_dest) @@ -3345,46 +3351,31 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; - if(cur == c) - continue; - if(!client_normal(cur)) - continue; - if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) - continue; - if(cur->iconic) - continue; - if(cur->layer < c->layer && !config_resist_layers_below) - continue; + WANT_EDGE(cur, c) his_edge_start = cur->frame->area.y; his_edge_end = cur->frame->area.y + cur->frame->area.height; - his_offset = cur->frame->area.x + cur->frame->area.width; + his_offset = cur->frame->area.x + + (hang ? 0 : cur->frame->area.width); if(his_offset + 1 > my_offset) continue; - + if(his_offset < dest) continue; - - if(his_edge_start >= my_edge_start && - his_edge_start <= my_edge_end) - dest = his_offset; - - if(my_edge_start >= his_edge_start && - my_edge_start <= his_edge_end) - dest = his_offset; - + HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) } - break; + break; case OB_DIRECTION_EAST: my_edge_start = c->frame->area.y; my_edge_end = c->frame->area.y + c->frame->area.height; - my_offset = c->frame->area.x + c->frame->area.width; + my_offset = c->frame->area.x + (hang ? 0 : c->frame->area.width); /* default: rightmost edge of screen */ - dest = a->x + a->width; - monitor_dest = monitor->x + monitor->width; + dest = a->x + a->width - (hang ? c->frame->area.width : 0); + monitor_dest = monitor->x + monitor->width - + (hang ? c->frame->area.width : 0); /* if the monitor edge comes before the screen edge, */ /* use that as the destination instead. (For xinerama) */ if (monitor_dest != dest && my_offset < monitor_dest) @@ -3394,35 +3385,20 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; - if(cur == c) - continue; - if(!client_normal(cur)) - continue; - if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) - continue; - if(cur->iconic) - continue; - if(cur->layer < c->layer && !config_resist_layers_below) - continue; + WANT_EDGE(cur, c) his_edge_start = cur->frame->area.y; his_edge_end = cur->frame->area.y + cur->frame->area.height; - his_offset = cur->frame->area.x; + his_offset = cur->frame->area.x + + (hang ? cur->frame->area.width : 0); if(his_offset - 1 < my_offset) continue; if(his_offset > dest) continue; - - if(his_edge_start >= my_edge_start && - his_edge_start <= my_edge_end) - dest = his_offset; - - if(my_edge_start >= his_edge_start && - my_edge_start <= his_edge_end) - dest = his_offset; + HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) } break; case OB_DIRECTION_NORTHEAST: