X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=2285bed853179db43500e66918340b58dd1cd4bb;hb=0417d1226c7a523cd4420195d86dd744f514b2fe;hp=a465f566326d58d29256d1addaef02eee7eef64b;hpb=b2b8ad92bfbc60392737fe9945e719b238d34933;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index a465f566..2285bed8 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -344,7 +344,7 @@ void client_manage(Window window) place_client(self, &x, &y); - /* make sure the window is visible */ + /* make sure the window is visible. */ client_find_onscreen(self, &x, &y, self->frame->area.width, self->frame->area.height, @@ -353,11 +353,13 @@ void client_manage(Window window) do also. we can assume you want it back where you saved it */ client_normal(self) && !self->session); - - if (x != ox || y != oy) + if (x != ox || y != oy) client_move(self, x, y); } + keyboard_grab_for_client(self, TRUE); + mouse_grab_for_client(self, TRUE); + client_showhide(self); /* use client_focus instead of client_activate cuz client_activate does @@ -392,9 +394,6 @@ void client_manage(Window window) /* update the list hints */ client_set_list(); - keyboard_grab_for_client(self, TRUE); - mouse_grab_for_client(self, TRUE); - ob_debug("Managed window 0x%lx (%s)\n", window, self->class); } @@ -460,8 +459,6 @@ void client_unmanage(ObClient *self) /* tell our parent(s) that we're gone */ if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */ - GSList *it; - for (it = self->group->members; it; it = g_slist_next(it)) if (it->data != self) ((ObClient*)it->data)->transients = @@ -613,7 +610,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, would be */ /* XXX watch for xinerama dead areas */ - + /* This makes sure windows aren't entirely outside of the screen so you + * can't see them at all */ a = screen_area(self->desktop); if (client_normal(self)) { if (!self->strut.right && *x >= a->x + a->width - 1) @@ -626,9 +624,16 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, *y = a->y; } - if (rude) { - /* this is my MOZILLA BITCHSLAP. oh ya it fucking feels good. - Java can suck it too. */ + /* This here doesn't let windows even a pixel outside the screen, + * not applied to all windows. Not sure if it's going to stay at all. + * I wonder if disabling this will break struts somehow? Let's find out. */ + if (0 && rude) { + /* avoid the xinerama monitor divide while we're at it, + * remember to fix the placement stuff to avoid it also and + * then remove this XXX */ + a = screen_physical_area_monitor(client_monitor(self)); + /* this is ben's MOZILLA BITCHSLAP. "oh ya it fucking feels good. + Java can suck it too." */ /* dont let windows map/move into the strut unless they are bigger than the available area */ @@ -1257,8 +1262,12 @@ void client_setup_decor_and_functions(ObClient *self) /* finally, the user can have requested no decorations, which overrides everything (but doesnt give it a border if it doesnt have one) */ - if (self->undecorated) - self->decorations = 0; //&= OB_FRAME_DECOR_BORDER; + if (self->undecorated) { + if (config_theme_keepborder) + self->decorations &= OB_FRAME_DECOR_BORDER; + else + self->decorations = 0; + } /* if we don't have a titlebar, then we cannot shade! */ if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR)) @@ -1442,14 +1451,17 @@ void client_update_title(ObClient *self) old_title = self->title; /* try netwm */ - if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) + if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) { /* try old x stuff */ - if (!PROP_GETS(self->window, wm_name, locale, &data)) + if (!PROP_GETS(self->window, wm_name, locale, &data)) { // http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html - if (self->transient) - data = '\0'; - else + if (self->transient) { + data = g_strdup(""); + goto no_number; + } else data = g_strdup("Unnamed Window"); + } + } /* did the title change? then reset the title_count */ if (old_title && 0 != strncmp(old_title, data, strlen(data))) @@ -1479,7 +1491,7 @@ void client_update_title(ObClient *self) } PROP_SETS(self->window, net_wm_visible_name, data); - +no_number: self->title = data; if (self->frame) @@ -1783,9 +1795,8 @@ static ObStackingLayer calc_layer(ObClient *self) else if (self->type == OB_CLIENT_TYPE_DESKTOP) l = OB_STACKING_LAYER_DESKTOP; else if (self->type == OB_CLIENT_TYPE_DOCK) { - if (self->above) l = OB_STACKING_LAYER_DOCK_ABOVE; - else if (self->below) l = OB_STACKING_LAYER_DOCK_BELOW; - else l = OB_STACKING_LAYER_DOCK_NORMAL; + if (self->below) l = OB_STACKING_LAYER_NORMAL; + else l = OB_STACKING_LAYER_ABOVE; } else if (self->above) l = OB_STACKING_LAYER_ABOVE; else if (self->below) l = OB_STACKING_LAYER_BELOW; @@ -2522,6 +2533,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) gboolean max_horz = self->max_horz; gboolean max_vert = self->max_vert; gboolean modal = self->modal; + gboolean iconic = self->iconic; gint i; if (!(action == prop_atoms.net_wm_state_add || @@ -2557,6 +2569,10 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) action = self->skip_pager ? prop_atoms.net_wm_state_remove : prop_atoms.net_wm_state_add; + else if (state == prop_atoms.net_wm_state_hidden) + action = self->iconic ? + prop_atoms.net_wm_state_remove : + prop_atoms.net_wm_state_add; else if (state == prop_atoms.net_wm_state_fullscreen) action = fullscreen ? prop_atoms.net_wm_state_remove : @@ -2585,6 +2601,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) self->skip_taskbar = TRUE; } else if (state == prop_atoms.net_wm_state_skip_pager) { self->skip_pager = TRUE; + } else if (state == prop_atoms.net_wm_state_hidden) { + iconic = TRUE; } else if (state == prop_atoms.net_wm_state_fullscreen) { fullscreen = TRUE; } else if (state == prop_atoms.net_wm_state_above) { @@ -2610,6 +2628,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) self->skip_taskbar = FALSE; } else if (state == prop_atoms.net_wm_state_skip_pager) { self->skip_pager = FALSE; + } else if (state == prop_atoms.net_wm_state_hidden) { + iconic = FALSE; } else if (state == prop_atoms.net_wm_state_fullscreen) { fullscreen = FALSE; } else if (state == prop_atoms.net_wm_state_above) { @@ -2652,6 +2672,9 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) transients needs to change */ client_raise(self); } + if (iconic != self->iconic) + client_iconify(self, iconic, FALSE); + client_calc_layer(self); client_change_state(self); /* change the hint to reflect these changes */ } @@ -2892,7 +2915,10 @@ ObClient *client_find_directional(ObClient *c, ObDirection dir) continue; if (!client_normal(cur)) continue; - if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + /* using c->desktop instead of screen_desktop doesn't work if the + * current window was omnipresent, hope this doesn't have any other + * side effects */ + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) continue; if(cur->iconic) continue; @@ -2982,10 +3008,19 @@ void client_set_undecorated(ObClient *self, gboolean undecorated) if (self->undecorated != undecorated) { self->undecorated = undecorated; client_setup_decor_and_functions(self); + // Make sure the client knows it might have moved. Maybe there is a + // better way of doing this so only one client_configure is sent, but + // since 125 of these are sent per second when moving the window (with + // user = FALSE) i doubt it matters much. + client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y, + self->area.width, self->area.height, TRUE, TRUE); client_change_state(self); /* reflect this in the state hints */ } } +/* Determines which physical monitor a client is on by calculating the + area of the part of the client on each monitor. The number of the + monitor containing the greatest area of the client is returned.*/ guint client_monitor(ObClient *self) { guint i; @@ -3112,15 +3147,16 @@ void client_update_sm_client_id(ObClient *self) */ gint client_directional_edge_search(ObClient *c, ObDirection dir) { - gint dest; + gint dest, monitor_dest; gint my_edge_start, my_edge_end, my_offset; GList *it; - Rect *a; + Rect *a, *monitor; if(!client_list) return -1; a = screen_area(c->desktop); + monitor = screen_area_monitor(c->desktop, client_monitor(c)); switch(dir) { case OB_DIRECTION_NORTH: @@ -3130,8 +3166,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) /* default: top of screen */ dest = a->y; + monitor_dest = monitor->y; + /* 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) + dest = monitor_dest; - for(it = client_list; it; it = g_list_next(it)) { + for(it = client_list; it && my_offset != dest; it = g_list_next(it)) { gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; @@ -3139,10 +3180,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) continue; if(!client_normal(cur)) continue; - if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) continue; if(cur->iconic) continue; + if(cur->layer < c->layer && !config_resist_layers_below) + continue; his_edge_start = cur->frame->area.x; his_edge_end = cur->frame->area.x + cur->frame->area.width; @@ -3171,8 +3214,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) /* default: bottom of screen */ dest = a->y + a->height; + monitor_dest = monitor->y + monitor->height; + /* 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) + dest = monitor_dest; - for(it = client_list; it; it = g_list_next(it)) { + for(it = client_list; it && my_offset != dest; it = g_list_next(it)) { gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; @@ -3180,10 +3228,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) continue; if(!client_normal(cur)) continue; - if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) continue; if(cur->iconic) continue; + if(cur->layer < c->layer && !config_resist_layers_below) + continue; his_edge_start = cur->frame->area.x; his_edge_end = cur->frame->area.x + cur->frame->area.width; @@ -3213,8 +3263,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) /* default: leftmost egde of screen */ dest = a->x; + monitor_dest = monitor->x; + /* 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) + dest = monitor_dest; - for(it = client_list; it; it = g_list_next(it)) { + for(it = client_list; it && my_offset != dest; it = g_list_next(it)) { gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; @@ -3222,10 +3277,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) continue; if(!client_normal(cur)) continue; - if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) continue; if(cur->iconic) continue; + if(cur->layer < c->layer && !config_resist_layers_below) + continue; his_edge_start = cur->frame->area.y; his_edge_end = cur->frame->area.y + cur->frame->area.height; @@ -3255,8 +3312,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) /* default: rightmost edge of screen */ dest = a->x + a->width; + monitor_dest = monitor->x + monitor->width; + /* 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) + dest = monitor_dest; - for(it = client_list; it; it = g_list_next(it)) { + for(it = client_list; it && my_offset != dest; it = g_list_next(it)) { gint his_edge_start, his_edge_end, his_offset; ObClient *cur = it->data; @@ -3264,10 +3326,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) continue; if(!client_normal(cur)) continue; - if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) continue; if(cur->iconic) continue; + if(cur->layer < c->layer && !config_resist_layers_below) + continue; his_edge_start = cur->frame->area.y; his_edge_end = cur->frame->area.y + cur->frame->area.height; @@ -3296,6 +3360,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir) /* not implemented */ default: g_assert_not_reached(); + dest = 0; /* suppress warning */ } return dest; }