summaryrefslogtreecommitdiff
path: root/mcwm.c
diff options
context:
space:
mode:
authorMC <mc@hack.org>2010-06-21 07:10:37 +0200
committerMC <mc@brain.hack.org>2010-06-21 07:10:37 +0200
commit52444e8146ac25461cfd2720c3c5a380269117f1 (patch)
tree753701999334de2c7bfccb0a3437249b7b231f09 /mcwm.c
parentc71ffa605d52222277e0ef998db25df0cdaf8163 (diff)
downloadmcwm-52444e8146ac25461cfd2720c3c5a380269117f1.zip
When we get a new window, check for size hints and compare them to the
initial geometry. If they disagree, use the size hints instead. Use 0,0 as origo! Duh. If we get a new very large window, resize it to fit our screen before mapping. Use the XCB_EVENT_MASK_STRUCTURE_NOTIFY mask on the root window, so we get CONFIGURE NOTIFY events from the root window itself! This means that if RANDR suddenly changes the geometry we get to know about it. Handle it gracefully.
Diffstat (limited to 'mcwm.c')
-rw-r--r--mcwm.c103
1 files changed, 89 insertions, 14 deletions
diff --git a/mcwm.c b/mcwm.c
index 63d59dc..0988f8a 100644
--- a/mcwm.c
+++ b/mcwm.c
@@ -131,9 +131,12 @@ void handle_keypress(xcb_drawable_t win, xcb_key_press_event_t *ev);
void newwin(xcb_window_t win)
{
xcb_query_pointer_reply_t *pointer;
- xcb_get_geometry_reply_t *geom;
+ xcb_get_geometry_reply_t *geom;
int x;
int y;
+ xcb_size_hints_t hints;
+ int32_t width;
+ int32_t height;
/* Get pointer position so we can move the window to the cursor. */
pointer = xcb_query_pointer_reply(
@@ -141,8 +144,8 @@ void newwin(xcb_window_t win)
if (NULL == pointer)
{
- x = 1;
- y = 1;
+ x = 0;
+ y = 0;
}
else
{
@@ -164,28 +167,69 @@ void newwin(xcb_window_t win)
return;
}
- /* If the window is larger than our screen, just place it in the corner. */
- if (geom->width > screen->width_in_pixels)
+ /* Get geometry hints. */
+ if (!xcb_get_wm_normal_hints_reply(
+ conn, xcb_get_wm_normal_hints_unchecked(
+ conn, win), &hints, NULL))
{
- x = 1;
+ PDEBUG("Couldn't get size hints.");
}
- else if (x + geom->width + BORDERWIDTH * 2 > screen->width_in_pixels)
+
+ if (hints.flags & XCB_SIZE_HINT_P_SIZE)
{
- x = screen->width_in_pixels - (geom->width + BORDERWIDTH * 2);
+ width = hints.width;
+ height = hints.height;
+
+ /*
+ * If the hints don't agree with the window geometry, resize
+ * the window to what the hints say. Needed for xterm, for
+ * example.
+ */
+ if (width != geom->width || height != geom->height)
+ {
+ resize(win, width, height);
+ }
+ }
+ else
+ {
+ width = geom->width;
+ height = geom->height;
+ }
+
+ PDEBUG("Hints say initial size of window: %d x %d (geom: %d x %d)\n",
+ width, height, geom->width, geom->height);
+
+ /* FIXME: XCB_SIZE_HINT_BASE_SIZE */
+
+ /*
+ * If the window is larger than our screen, just place it in the
+ * corner and resize.
+ */
+ if (width > screen->width_in_pixels)
+ {
+ x = 0;
+ width = screen->width_in_pixels - BORDERWIDTH * 2;;
+ resize(win, width, height);
+ }
+ else if (x + width + BORDERWIDTH * 2 > screen->width_in_pixels)
+ {
+ x = screen->width_in_pixels - (width + BORDERWIDTH * 2);
}
- if (geom->height > screen->width_in_pixels)
+ if (height > screen->height_in_pixels)
{
- y = 1;
+ y = 0;
+ height = screen->height_in_pixels - BORDERWIDTH * 2;
+ resize(win, width, height);
}
- else if (y + geom->height + BORDERWIDTH * 2 > screen->height_in_pixels)
+ else if (y + height + BORDERWIDTH * 2 > screen->height_in_pixels)
{
- y = screen->height_in_pixels - (geom->height + BORDERWIDTH * 2);
+ y = screen->height_in_pixels - (height + BORDERWIDTH * 2);
}
/* Move the window to cursor position. */
movewindow(win, x, y);
-
+
/* Set up stuff and raise the window. */
setupwin(win);
raisewindow(win);
@@ -1120,7 +1164,6 @@ void events(void)
case XCB_MOTION_NOTIFY:
{
- xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t *)ev;
xcb_query_pointer_reply_t *pointer;
/*
@@ -1210,8 +1253,39 @@ void events(void)
}
}
break;
+
+ case XCB_CONFIGURE_NOTIFY:
+ {
+ xcb_configure_notify_event_t *e = (xcb_configure_notify_event_t *)ev;
+
+ if (e->window == screen->root)
+ {
+ /*
+ * When using RANDR, the root can suddenly change
+ * geometry when the user adds a new screen, tilts
+ * their screen 90 degrees or whatnot.
+ *
+ * Since mcwm cares about the root edges, we need to
+ * update our view if this happens.
+ */
+ PDEBUG("Notify event for root!\n");
+
+ screen->width_in_pixels = e->width;
+ screen->height_in_pixels = e->height;
+
+ PDEBUG("New root geometry: %dx%d\n", e->width, e->height);
+
+ /*
+ * FIXME: If the root suddenly got a lot smaller and
+ * some windows are outside of the root window, we
+ * need to rearrange them.
+ */
+ }
+ }
+ break;
} /* switch */
+
free(ev);
}
@@ -1308,6 +1382,7 @@ int main(int argc, char **argv)
mask = XCB_CW_EVENT_MASK;
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
+ | XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
cookie =