X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fframe.c;h=dc9d16014ecb0f2f4f89db6644a646c1833dece4;hb=fb2493115fd152e0f2247935eed1cbaca2f0ba6d;hp=953ed07d1e5c889037a13c7ba249ce2e8708094d;hpb=56307d60773d0eaf65b10414cd0e3ec0b2adc156;p=chaz%2Fopenbox diff --git a/openbox/frame.c b/openbox/frame.c index 953ed07d..dc9d1601 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -2,7 +2,7 @@ frame.c for the Openbox window manager Copyright (c) 2006 Mikael Magnusson - Copyright (c) 2003 Ben Jansens + Copyright (c) 2003-2007 Dana Jansens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,13 +29,17 @@ #include "moveresize.h" #include "render/theme.h" -#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask) +#define PLATE_EVENTMASK (SubstructureRedirectMask | FocusChangeMask) #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \ - ButtonPressMask | ButtonReleaseMask | \ - VisibilityChangeMask) + ButtonPressMask | ButtonReleaseMask) #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \ - ButtonMotionMask | ExposureMask | \ + ButtonMotionMask | \ EnterWindowMask | LeaveWindowMask) +/* The inner window does not need enter/leave events. + If it does get them, then it needs its own context for enter events + because sloppy focus will focus the window when you enter the inner window + from the frame. */ +#define INNER_EVENTMASK (ButtonPressMask) #define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \ f->cbwidth_y) @@ -80,8 +84,6 @@ ObFrame *frame_new(ObClient *client) self = g_new0(ObFrame, 1); - self->obscured = TRUE; - visual = check_32bit_client(client); /* create the non-visible decor windows */ @@ -101,8 +103,12 @@ ObFrame *frame_new(ObClient *client) attrib.event_mask = FRAME_EVENTMASK; self->window = createWindow(RootWindow(ob_display, ob_screen), visual, mask, &attrib); + + attrib.event_mask = INNER_EVENTMASK; + self->inner = createWindow(self->window, visual, mask, &attrib); + mask &= ~CWEventMask; - self->plate = createWindow(self->window, visual, mask, &attrib); + self->plate = createWindow(self->inner, visual, mask, &attrib); /* create the visible decor windows */ @@ -143,6 +149,7 @@ ObFrame *frame_new(ObClient *client) /* the other stuff is shown based on decor settings */ XMapWindow(ob_display, self->plate); + XMapWindow(ob_display, self->inner); XMapWindow(ob_display, self->lgrip); XMapWindow(ob_display, self->rgrip); XMapWindow(ob_display, self->label); @@ -244,7 +251,7 @@ void frame_hide(ObFrame *self) { if (self->visible) { self->visible = FALSE; - self->client->ignore_unmaps += 2; + self->client->ignore_unmaps += 1; /* we unmap the client itself so that we can get MapRequest events, and because the ICCCM tells us to! */ XUnmapWindow(ob_display, self->window); @@ -420,15 +427,22 @@ void frame_adjust_area(ObFrame *self, gboolean moved, } else XUnmapWindow(ob_display, self->handle); - /* move and resize the plate */ - XMoveResizeWindow(ob_display, self->plate, + /* move and resize the inner border window which contains the plate + */ + XMoveResizeWindow(ob_display, self->inner, self->innersize.left - self->cbwidth_x, self->innersize.top - self->cbwidth_y, - self->client->area.width + self->cbwidth_x * 2, - self->client->area.height + self->cbwidth_y * 2); - /* when the client has StaticGravity, it likes to move around. */ - XMoveWindow(ob_display, self->client->window, + self->client->area.width + + self->cbwidth_x * 2, + self->client->area.height + + self->cbwidth_y * 2); + + /* move the plate */ + XMoveWindow(ob_display, self->plate, self->cbwidth_x, self->cbwidth_y); + + /* when the client has StaticGravity, it likes to move around. */ + XMoveWindow(ob_display, self->client->window, 0, 0); } STRUT_SET(self->size, @@ -474,7 +488,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, vals[1] = self->size.right; vals[2] = self->size.top; vals[3] = self->size.bottom; - PROP_SETA32(self->client->window, kde_net_wm_frame_strut, + PROP_SETA32(self->client->window, net_frame_extents, cardinal, vals, 4); } @@ -497,6 +511,14 @@ void frame_adjust_focus(ObFrame *self, gboolean hilite) { self->focused = hilite; framerender_frame(self); + XFlush(ob_display); +} + +void frame_adjust_client_area(ObFrame *self) +{ + /* resize the plate */ + XResizeWindow(ob_display, self->plate, + self->client->area.width, self->client->area.height); } void frame_adjust_title(ObFrame *self) @@ -530,14 +552,15 @@ void frame_grab_client(ObFrame *self, ObClient *client) req's) the ButtonPress is to catch clicks on the client border */ XSelectInput(ob_display, self->plate, PLATE_EVENTMASK); + frame_adjust_area(self, TRUE, TRUE, FALSE); + /* map the client so it maps when the frame does */ XMapWindow(ob_display, client->window); - frame_adjust_area(self, TRUE, TRUE, FALSE); - /* set all the windows for the frame in the window_map */ g_hash_table_insert(window_map, &self->window, client); g_hash_table_insert(window_map, &self->plate, client); + g_hash_table_insert(window_map, &self->inner, client); g_hash_table_insert(window_map, &self->title, client); g_hash_table_insert(window_map, &self->label, client); g_hash_table_insert(window_map, &self->max, client); @@ -592,6 +615,7 @@ void frame_release_client(ObFrame *self, ObClient *client) /* remove all the windows for the frame from the window_map */ g_hash_table_remove(window_map, &self->window); g_hash_table_remove(window_map, &self->plate); + g_hash_table_remove(window_map, &self->inner); g_hash_table_remove(window_map, &self->title); g_hash_table_remove(window_map, &self->label); g_hash_table_remove(window_map, &self->max); @@ -804,7 +828,7 @@ ObFrameContext frame_context(ObClient *client, Window win) } self = client->frame; - if (win == self->plate) { + if (win == self->inner || win == self->plate) { /* conceptually, this is the desktop, as far as users are concerned */ if (client->type == OB_CLIENT_TYPE_DESKTOP) @@ -812,22 +836,22 @@ ObFrameContext frame_context(ObClient *client, Window win) return OB_FRAME_CONTEXT_CLIENT; } - if (win == self->window) return OB_FRAME_CONTEXT_FRAME; - if (win == self->title) return OB_FRAME_CONTEXT_TITLEBAR; - if (win == self->label) return OB_FRAME_CONTEXT_TITLEBAR; - if (win == self->handle) return OB_FRAME_CONTEXT_HANDLE; - if (win == self->lgrip) return OB_FRAME_CONTEXT_BLCORNER; - if (win == self->rgrip) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->window) return OB_FRAME_CONTEXT_FRAME; + if (win == self->title) return OB_FRAME_CONTEXT_TITLEBAR; + if (win == self->label) return OB_FRAME_CONTEXT_TITLEBAR; + if (win == self->handle) return OB_FRAME_CONTEXT_HANDLE; + if (win == self->lgrip) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->rgrip) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->tltresize) return OB_FRAME_CONTEXT_TLCORNER; if (win == self->tllresize) return OB_FRAME_CONTEXT_TLCORNER; if (win == self->trtresize) return OB_FRAME_CONTEXT_TRCORNER; if (win == self->trrresize) return OB_FRAME_CONTEXT_TRCORNER; - if (win == self->max) return OB_FRAME_CONTEXT_MAXIMIZE; - if (win == self->iconify) return OB_FRAME_CONTEXT_ICONIFY; - if (win == self->close) return OB_FRAME_CONTEXT_CLOSE; - if (win == self->icon) return OB_FRAME_CONTEXT_ICON; - if (win == self->desk) return OB_FRAME_CONTEXT_ALLDESKTOPS; - if (win == self->shade) return OB_FRAME_CONTEXT_SHADE; + if (win == self->max) return OB_FRAME_CONTEXT_MAXIMIZE; + if (win == self->iconify) return OB_FRAME_CONTEXT_ICONIFY; + if (win == self->close) return OB_FRAME_CONTEXT_CLOSE; + if (win == self->icon) return OB_FRAME_CONTEXT_ICON; + if (win == self->desk) return OB_FRAME_CONTEXT_ALLDESKTOPS; + if (win == self->shade) return OB_FRAME_CONTEXT_SHADE; return OB_FRAME_CONTEXT_NONE; } @@ -976,6 +1000,7 @@ void frame_flash_start(ObFrame *self) G_USEC_PER_SEC * 0.6, flash_timeout, self, + g_direct_equal, flash_done); g_get_current_time(&self->flash_end); g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5);