Index: uspace/app/vdemo/vdemo.c
===================================================================
--- uspace/app/vdemo/vdemo.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/app/vdemo/vdemo.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -110,5 +110,5 @@
 {
 	if (argc >= 2) {
-		window_t *main_window = window_open(argv[1], true, true, "vdemo", 0, 0);
+		window_t *main_window = window_open(argv[1], true, true, "vdemo");
 		if (!main_window) {
 			printf("Cannot open main window.\n");
@@ -150,5 +150,6 @@
 		grid->add(grid, &btn_confirm->widget, 0, 1, 1, 1);
 		grid->add(grid, &btn_cancel->widget, 1, 1, 1, 1);
-		window_resize(main_window, 200, 76);
+		window_resize(main_window, 0, 0, 200, 76,
+		    WINDOW_PLACEMENT_CENTER);
 
 		window_exec(main_window);
Index: uspace/app/viewer/viewer.c
===================================================================
--- uspace/app/viewer/viewer.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/app/viewer/viewer.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -166,5 +166,5 @@
 	}
 	
-	main_window = window_open(argv[1], true, false, "viewer", 0, 0);
+	main_window = window_open(argv[1], true, false, "viewer");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
@@ -192,5 +192,6 @@
 	}
 	
-	window_resize(main_window, WINDOW_WIDTH, WINDOW_HEIGHT);
+	window_resize(main_window, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
+	    WINDOW_PLACEMENT_ABSOLUTE);
 	window_exec(main_window);
 	
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/app/vlaunch/vlaunch.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -115,5 +115,5 @@
 	
 	winreg = argv[1];
-	window_t *main_window = window_open(argv[1], true, true, "vlaunch", 0, 0);
+	window_t *main_window = window_open(argv[1], true, true, "vlaunch");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
@@ -159,5 +159,6 @@
 	grid->add(grid, &btn_vlaunch->widget, 0, 4, 1, 1);
 	
-	window_resize(main_window, 210, 130 + LOGO_HEIGHT);
+	window_resize(main_window, 0, 0, 210, 130 + LOGO_HEIGHT,
+	    WINDOW_PLACEMENT_RIGHT | WINDOW_PLACEMENT_TOP);
 	window_exec(main_window);
 	
Index: uspace/app/vterm/vterm.c
===================================================================
--- uspace/app/vterm/vterm.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/app/vterm/vterm.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -49,5 +49,5 @@
 	}
 	
-	window_t *main_window = window_open(argv[1], true, true, "vterm", 0, 0);
+	window_t *main_window = window_open(argv[1], true, true, "vterm");
 	if (!main_window) {
 		printf("%s: Cannot open main window.\n", NAME);
@@ -55,5 +55,5 @@
 	}
 	
-	window_resize(main_window, 648, 510);
+	window_resize(main_window, 0, 0, 648, 510, WINDOW_PLACEMENT_ANY);
 	terminal_t *terminal_widget =
 	    create_terminal(window_root(main_window), 640, 480);
Index: uspace/lib/c/generic/io/window.c
===================================================================
--- uspace/lib/c/generic/io/window.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/lib/c/generic/io/window.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -40,11 +40,10 @@
 #include <stdio.h>
 
-int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out, 
-    sysarg_t x_offset, sysarg_t y_offset)
+int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	int ret = async_req_2_2(exch, WINDOW_REGISTER, x_offset, y_offset, in, out);
+	int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
 	async_exchange_end(exch);
-
+	
 	return ret;
 }
@@ -92,25 +91,26 @@
 }
 
-int win_resize(async_sess_t *sess, sysarg_t width, sysarg_t height, void *cells)
+int win_resize(async_sess_t *sess, sysarg_t x, sysarg_t y, sysarg_t width,
+    sysarg_t height, window_placement_flags_t placement_flags, void *cells)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-
+	
 	ipc_call_t answer;
-	aid_t req = async_send_2(exch, WINDOW_RESIZE, width, height, &answer);
-
+	aid_t req = async_send_5(exch, WINDOW_RESIZE, x, y, width, height,
+	    (sysarg_t) placement_flags, &answer);
+	
 	int rc = async_share_out_start(exch, cells, AS_AREA_READ | AS_AREA_CACHEABLE);
-
+	
 	async_exchange_end(exch);
-
+	
 	sysarg_t ret;
 	async_wait_for(req, &ret);
-
-	if (rc != EOK) {
+	
+	if (rc != EOK)
 		return rc;
-	} else if (ret != EOK) {
+	else if (ret != EOK)
 		return ret;
-	} else {
-		return EOK;
-	}
+	
+	return EOK;
 }
 
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/lib/c/include/io/window.h	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -43,14 +43,43 @@
 #include <io/pos_event.h>
 
+typedef enum {
+	GF_EMPTY = 0,
+	GF_MOVE_X = 1,
+	GF_MOVE_Y = 2,
+	GF_RESIZE_X = 4,
+	GF_RESIZE_Y = 8,
+	GF_SCALE_X = 16,
+	GF_SCALE_Y = 32
+} window_grab_flags_t;
+
+typedef enum {
+	WINDOW_PLACEMENT_ANY = 0,
+	WINDOW_PLACEMENT_CENTER_X = 1,
+	WINDOW_PLACEMENT_CENTER_Y = 2,
+	WINDOW_PLACEMENT_CENTER =
+	    WINDOW_PLACEMENT_CENTER_X | WINDOW_PLACEMENT_CENTER_Y,
+	WINDOW_PLACEMENT_LEFT = 4,
+	WINDOW_PLACEMENT_RIGHT = 8,
+	WINDOW_PLACEMENT_TOP = 16,
+	WINDOW_PLACEMENT_BOTTOM = 32,
+	WINDOW_PLACEMENT_ABSOLUTE_X = 64,
+	WINDOW_PLACEMENT_ABSOLUTE_Y = 128,
+	WINDOW_PLACEMENT_ABSOLUTE =
+	    WINDOW_PLACEMENT_ABSOLUTE_X | WINDOW_PLACEMENT_ABSOLUTE_Y
+} window_placement_flags_t;
+
 typedef struct {
 	sysarg_t object;
 	sysarg_t slot;
 	sysarg_t argument;
-} sig_event_t;
+} signal_event_t;
 
 typedef struct {
+	sysarg_t offset_x;
+	sysarg_t offset_y;
 	sysarg_t width;
 	sysarg_t height;
-} rsz_event_t;
+	window_placement_flags_t placement_flags;
+} resize_event_t;
 
 typedef enum {
@@ -69,6 +98,6 @@
 	kbd_event_t kbd;
 	pos_event_t pos;
-	sig_event_t sig;
-	rsz_event_t rsz;
+	signal_event_t signal;
+	resize_event_t resize;
 } window_event_data_t;
 
@@ -79,15 +108,5 @@
 } window_event_t;
 
-typedef enum {
-	GF_EMPTY = 0,
-	GF_MOVE_X = 1,
-	GF_MOVE_Y = 2,
-	GF_RESIZE_X = 4,
-	GF_RESIZE_Y = 8,
-	GF_SCALE_X = 16,
-	GF_SCALE_Y = 32
-} window_grab_flags_t;
-
-extern int win_register(async_sess_t *, service_id_t *, service_id_t *, sysarg_t, sysarg_t);
+extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
 
 extern int win_get_event(async_sess_t *, window_event_t *);
@@ -95,5 +114,6 @@
 extern int win_damage(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
 extern int win_grab(async_sess_t *, sysarg_t, sysarg_t);
-extern int win_resize(async_sess_t *, sysarg_t, sysarg_t, void *);
+extern int win_resize(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t, void *);
 extern int win_close(async_sess_t *);
 extern int win_close_request(async_sess_t *);
Index: uspace/lib/gui/connection.c
===================================================================
--- uspace/lib/gui/connection.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/lib/gui/connection.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -210,7 +210,7 @@
 			link_initialize(&event->link);
 			event->type = ET_SIGNAL_EVENT;
-			event->data.sig.object = (sysarg_t) cur->widget;
-			event->data.sig.slot = (sysarg_t) cur->slot;
-			event->data.sig.argument = (sysarg_t) data_copy;
+			event->data.signal.object = (sysarg_t) cur->widget;
+			event->data.signal.slot = (sysarg_t) cur->slot;
+			event->data.signal.argument = (sysarg_t) data_copy;
 			prodcons_produce(&cur->widget->window->events, &event->link);
 		} else {
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/lib/gui/window.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -352,5 +352,5 @@
 }
 
-static void handle_signal_event(window_t *win, sig_event_t event)
+static void handle_signal_event(window_t *win, signal_event_t event)
 {
 	widget_t *widget = (widget_t *) event.object;
@@ -363,58 +363,56 @@
 }
 
-static void handle_resize(window_t *win, sysarg_t width, sysarg_t height)
-{
-	int rc;
-	surface_t *old_surface;
-	surface_t *new_surface;
-
+static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
+    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
+{
 	if (width < 2 * border_thickness + header_min_width) {
 		win_damage(win->osess, 0, 0, 0, 0);
 		return;
 	}
-
+	
 	if (height < 2 * border_thickness + header_height) {
 		win_damage(win->osess, 0, 0, 0, 0);
 		return;
 	}
-
+	
 	/* Allocate resources for new surface. */
-	new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED);
-	if (!new_surface) {
+	surface_t *new_surface = surface_create(width, height, NULL,
+	    SURFACE_FLAG_SHARED);
+	if (!new_surface)
 		return;
-	}
-
+	
 	/* Switch new and old surface. */
 	fibril_mutex_lock(&win->guard);
-	old_surface = win->surface;
+	surface_t *old_surface = win->surface;
 	win->surface = new_surface;
 	fibril_mutex_unlock(&win->guard);
-
-	/* Let all widgets in the tree alter their position and size. Widgets might
-	 * also paint themselves onto the new surface. */
+	
+	/*
+	 * Let all widgets in the tree alter their position and size.
+	 * Widgets might also paint themselves onto the new surface.
+	 */
 	win->root.rearrange(&win->root, 0, 0, width, height);
-
+	
 	fibril_mutex_lock(&win->guard);
 	surface_reset_damaged_region(win->surface);
 	fibril_mutex_unlock(&win->guard);
-
+	
 	/* Inform compositor about new surface. */
-	rc = win_resize(win->osess,
-		width, height, surface_direct_access(new_surface));
-
+	int rc = win_resize(win->osess, offset_x, offset_y, width, height,
+	    placement_flags, surface_direct_access(new_surface));
+	
 	if (rc != EOK) {
 		/* Rollback to old surface. Reverse all changes. */
-
+		
 		sysarg_t old_width = 0;
 		sysarg_t old_height = 0;
-		if (old_surface) {
+		if (old_surface)
 			surface_get_resolution(old_surface, &old_width, &old_height);
-		}
-
+		
 		fibril_mutex_lock(&win->guard);
 		new_surface = win->surface;
 		win->surface = old_surface;
 		fibril_mutex_unlock(&win->guard);
-
+		
 		win->root.rearrange(&win->root, 0, 0, old_width, old_height);
 		
@@ -424,12 +422,10 @@
 			fibril_mutex_unlock(&win->guard);
 		}
-
+		
 		surface_destroy(new_surface);
-		return;
-	}
-
-	/* Finally deallocate old surface. */
-	if (old_surface) {
-		surface_destroy(old_surface);
+	} else {
+		/* Deallocate old surface. */
+		if (old_surface)
+			surface_destroy(old_surface);
 	}
 }
@@ -513,8 +509,10 @@
 			break;
 		case ET_SIGNAL_EVENT:
-			handle_signal_event(win, event->data.sig);
+			handle_signal_event(win, event->data.signal);
 			break;
 		case ET_WINDOW_RESIZE:
-			handle_resize(win, event->data.rsz.width, event->data.rsz.height);
+			handle_resize(win, event->data.resize.offset_x,
+			    event->data.resize.offset_y, event->data.resize.width,
+			    event->data.resize.height, event->data.resize.placement_flags);
 			break;
 		case ET_WINDOW_FOCUS:
@@ -590,5 +588,5 @@
 
 window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
-    const char *caption, sysarg_t x_offset, sysarg_t y_offset)
+    const char *caption)
 {
 	window_t *win = (window_t *) malloc(sizeof(window_t));
@@ -630,5 +628,5 @@
 	service_id_t in_dsid;
 	service_id_t out_dsid;
-	rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
+	rc = win_register(reg_sess, &in_dsid, &out_dsid);
 	async_hangup(reg_sess);
 	if (rc != EOK) {
@@ -658,5 +656,6 @@
 }
 
-void window_resize(window_t *win, sysarg_t width, sysarg_t height)
+void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
+    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
 {
 	window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
@@ -664,6 +663,9 @@
 		link_initialize(&event->link);
 		event->type = ET_WINDOW_RESIZE;
-		event->data.rsz.width = width;
-		event->data.rsz.height = height;
+		event->data.resize.offset_x = offset_x;
+		event->data.resize.offset_y = offset_y;
+		event->data.resize.width = width;
+		event->data.resize.height = height;
+		event->data.resize.placement_flags = placement_flags;
 		prodcons_produce(&win->events, &event->link);
 	}
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/lib/gui/window.h	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -66,6 +66,5 @@
  * If the window is declared as main, its closure causes termination of the
  * whole application. Note that opened window does not have any surface yet. */
-extern window_t *window_open(const char *, bool, bool, const char *, sysarg_t,
-    sysarg_t);
+extern window_t *window_open(const char *, bool, bool, const char *);
 
 /**
@@ -74,5 +73,6 @@
  * and to paint themselves on the new surface (top-bottom order). Should be
  * called also after opening new window to obtain surface. */
-extern void window_resize(window_t *, sysarg_t, sysarg_t);
+extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t);
 
 /**
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision ba02baac3c7ab204e742fe94ecb756dd60e8fb91)
+++ uspace/srv/hid/compositor/compositor.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -166,5 +166,5 @@
 }
 
-static pointer_t *pointer_create()
+static pointer_t *pointer_create(void)
 {
 	pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
@@ -208,5 +208,5 @@
 }
 
-static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
+static window_t *window_create(void)
 {
 	window_t *win = (window_t *) malloc(sizeof(window_t));
@@ -218,8 +218,7 @@
 	prodcons_initialize(&win->queue);
 	transform_identity(&win->transform);
-	transform_translate(&win->transform,
-	    coord_origin + x_offset, coord_origin + y_offset);
-	win->dx = coord_origin + x_offset;
-	win->dy = coord_origin + y_offset;
+	transform_translate(&win->transform, coord_origin, coord_origin);
+	win->dx = coord_origin;
+	win->dy = coord_origin;
 	win->fx = 1;
 	win->fy = 1;
@@ -321,13 +320,13 @@
 }
 
-static void comp_restrict_pointers(void)
+static void comp_update_viewport_bound_rect(void)
 {
 	fibril_mutex_lock(&viewport_list_mtx);
-
+	
 	sysarg_t x_res = coord_origin;
 	sysarg_t y_res = coord_origin;
 	sysarg_t w_res = 0;
 	sysarg_t h_res = 0;
-
+	
 	if (!list_empty(&viewport_list)) {
 		viewport_t *vp = (viewport_t *) list_first(&viewport_list);
@@ -336,23 +335,27 @@
 		surface_get_resolution(vp->surface, &w_res, &h_res);
 	}
-
+	
 	list_foreach(viewport_list, link, viewport_t, vp) {
 		sysarg_t w_vp, h_vp;
 		surface_get_resolution(vp->surface, &w_vp, &h_vp);
-		rectangle_union(
-		    x_res, y_res, w_res, h_res,
+		rectangle_union(x_res, y_res, w_res, h_res,
 		    vp->pos.x, vp->pos.y, w_vp, h_vp,
 		    &x_res, &y_res, &w_res, &h_res);
 	}
-
+	
 	viewport_bound_rect.x = x_res;
 	viewport_bound_rect.y = y_res;
 	viewport_bound_rect.w = w_res;
 	viewport_bound_rect.h = h_res;
-
+	
 	fibril_mutex_unlock(&viewport_list_mtx);
-
+}
+
+static void comp_restrict_pointers(void)
+{
+	comp_update_viewport_bound_rect();
+	
 	fibril_mutex_lock(&pointer_list_mtx);
-
+	
 	list_foreach(pointer_list, link, pointer_t, ptr) {
 		ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
@@ -363,5 +366,5 @@
 		    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
 	}
-
+	
 	fibril_mutex_unlock(&pointer_list_mtx);
 }
@@ -642,4 +645,33 @@
 }
 
+static void comp_recalc_transform(window_t *win)
+{
+	transform_t translate;
+	transform_identity(&translate);
+	transform_translate(&translate, win->dx, win->dy);
+	
+	transform_t scale;
+	transform_identity(&scale);
+	if ((win->fx != 1) || (win->fy != 1))
+		transform_scale(&scale, win->fx, win->fy);
+	
+	transform_t rotate;
+	transform_identity(&rotate);
+	if (win->angle != 0)
+		transform_rotate(&rotate, win->angle);
+	
+	transform_t transform;
+	transform_t temp;
+	transform_identity(&transform);
+	temp = transform;
+	transform_multiply(&transform, &temp, &translate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &rotate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &scale);
+	
+	win->transform = transform;
+}
+
 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
 {
@@ -662,6 +694,6 @@
 	
 	/* Create new surface for the resized window. */
-	surface_t *new_surface = surface_create(IPC_GET_ARG1(*icall),
-	    IPC_GET_ARG2(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
+	surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
+	    IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
 	if (!new_surface) {
 		as_area_destroy(new_cell_storage);
@@ -670,4 +702,11 @@
 	}
 	
+	sysarg_t offset_x = IPC_GET_ARG1(*icall);
+	sysarg_t offset_y = IPC_GET_ARG2(*icall);
+	window_placement_flags_t placement_flags =
+	    (window_placement_flags_t) IPC_GET_ARG5(*icall);
+	
+	comp_update_viewport_bound_rect();
+	
 	/* Switch new surface with old surface and calculate damage. */
 	fibril_mutex_lock(&window_list_mtx);
@@ -687,10 +726,58 @@
 	surface_get_resolution(win->surface, &new_width, &new_height);
 	
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 -
+		    new_width / 2;
+	
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 -
+		    new_height / 2;
+	
+	if (placement_flags & WINDOW_PLACEMENT_LEFT)
+		win->dx = viewport_bound_rect.x;
+	
+	if (placement_flags & WINDOW_PLACEMENT_TOP)
+		win->dy = viewport_bound_rect.y;
+	
+	if (placement_flags & WINDOW_PLACEMENT_RIGHT)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w -
+		    new_width;
+	
+	if (placement_flags & WINDOW_PLACEMENT_BOTTOM)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h -
+		    new_height;
+	
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X)
+		win->dx = coord_origin + offset_x;
+	
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y)
+		win->dy = coord_origin + offset_y;
+	
+	/* Transform the window and calculate damage. */
+	sysarg_t x1;
+	sysarg_t y1;
+	sysarg_t width1;
+	sysarg_t height1;
+	
+	comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform,
+	    &x1, &y1, &width1, &height1);
+	
+	comp_recalc_transform(win);
+	
+	sysarg_t x2;
+	sysarg_t y2;
+	sysarg_t width2;
+	sysarg_t height2;
+	
+	comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform,
+	    &x2, &y2, &width2, &height2);
+	
 	sysarg_t x;
 	sysarg_t y;
-	sysarg_t width = old_width > new_width ? old_width : new_width;
-	sysarg_t height = old_height > new_height ? old_height : new_height;
-	comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y,
-	    &width, &height);
+	sysarg_t width;
+	sysarg_t height;
+	
+	rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+	    &x, &y, &width, &height);
 	
 	fibril_mutex_unlock(&window_list_mtx);
@@ -803,5 +890,5 @@
 			fibril_mutex_lock(&window_list_mtx);
 
-			window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			window_t *win = window_create();
 			if (!win) {
 				async_answer_2(callid, ENOMEM, 0, 0);
@@ -1173,33 +1260,4 @@
 
 	return vp;
-}
-
-static void comp_recalc_transform(window_t *win)
-{
-	transform_t translate;
-	transform_identity(&translate);
-	transform_translate(&translate, win->dx, win->dy);
-	
-	transform_t scale;
-	transform_identity(&scale);
-	if ((win->fx != 1) || (win->fy != 1))
-		transform_scale(&scale, win->fx, win->fy);
-	
-	transform_t rotate;
-	transform_identity(&rotate);
-	if (win->angle != 0)
-		transform_rotate(&rotate, win->angle);
-	
-	transform_t transform;
-	transform_t temp;
-	transform_identity(&transform);
-	temp = transform;
-	transform_multiply(&transform, &temp, &translate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &rotate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &scale);
-	
-	win->transform = transform;
 }
 
@@ -1247,5 +1305,5 @@
 	}
 
-	if (scale || resize) {
+	if ((scale) || (resize)) {
 		double _dx = dx;
 		double _dy = dy;
@@ -1445,24 +1503,29 @@
 {
 	pointer_t *pointer = input_pointer(input);
-
+	
+	comp_update_viewport_bound_rect();
+	
 	/* Update pointer position. */
 	fibril_mutex_lock(&pointer_list_mtx);
+	
 	desktop_point_t old_pos = pointer->pos;
+	
 	sysarg_t cursor_width;
 	sysarg_t cursor_height;
-	surface_get_resolution(pointer->cursor.states[pointer->state], 
+	surface_get_resolution(pointer->cursor.states[pointer->state],
 	     &cursor_width, &cursor_height);
-	if (pointer->pos.x + dx < viewport_bound_rect.x) {
+	
+	if (pointer->pos.x + dx < viewport_bound_rect.x)
 		dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
-	}
-	if (pointer->pos.y + dy < viewport_bound_rect.y) {
+	
+	if (pointer->pos.y + dy < viewport_bound_rect.y)
 		dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
-	}
-	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {
+	
+	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w)
 		dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
-	}
-	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {
+	
+	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h)
 		dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
-	}
+	
 	pointer->pos.x += dx;
 	pointer->pos.y += dy;
@@ -1470,5 +1533,5 @@
 	comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
 	comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
-
+	
 	fibril_mutex_lock(&window_list_mtx);
 	fibril_mutex_lock(&pointer_list_mtx);
@@ -1631,5 +1694,5 @@
 
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-		sysarg_t pre_x = 0; 
+		sysarg_t pre_x = 0;
 		sysarg_t pre_y = 0;
 		sysarg_t pre_width = 0;
@@ -1663,21 +1726,25 @@
 				link_initialize(&event_top->link);
 				event_top->type = ET_WINDOW_RESIZE;
-
+				
+				event_top->data.resize.offset_x = 0;
+				event_top->data.resize.offset_y = 0;
+				
 				int dx = (int) (((double) width) * (scale_back_x - 1.0));
 				int dy = (int) (((double) height) * (scale_back_y - 1.0));
-
-				if (pointer->grab_flags & GF_RESIZE_X) {
-					event_top->data.rsz.width =
-						((((int) width) + dx) >= 0) ? (width + dx) : 0;
-				} else {
-					event_top->data.rsz.width = width;
-				}
-
-				if (pointer->grab_flags & GF_RESIZE_Y) {
-					event_top->data.rsz.height =
-						((((int) height) + dy) >= 0) ? (height + dy) : 0;
-				} else {
-					event_top->data.rsz.height = height;
-				}
+				
+				if (pointer->grab_flags & GF_RESIZE_X)
+					event_top->data.resize.width =
+					    ((((int) width) + dx) >= 0) ? (width + dx) : 0;
+				else
+					event_top->data.resize.width = width;
+				
+				if (pointer->grab_flags & GF_RESIZE_Y)
+					event_top->data.resize.height =
+					    ((((int) height) + dy) >= 0) ? (height + dy) : 0;
+				else
+					event_top->data.resize.height = height;
+				
+				event_top->data.resize.placement_flags =
+				    WINDOW_PLACEMENT_ANY;
 			}
 
@@ -1816,34 +1883,39 @@
 				return ENOMEM;
 			}
-
+			
 			sysarg_t width, height;
 			surface_get_resolution(win->surface, &width, &height);
-
+			
 			link_initialize(&event->link);
 			event->type = ET_WINDOW_RESIZE;
-
+			
+			event->data.resize.offset_x = 0;
+			event->data.resize.offset_y = 0;
+			
 			switch (key) {
 			case KC_T:
-				event->data.rsz.width = width;
-				event->data.rsz.height = (height >= 20) ? height - 20 : 0;
+				event->data.resize.width = width;
+				event->data.resize.height = (height >= 20) ? height - 20 : 0;
 				break;
 			case KC_G:
-				event->data.rsz.width = width;
-				event->data.rsz.height = height + 20;
+				event->data.resize.width = width;
+				event->data.resize.height = height + 20;
 				break;
 			case KC_B:
-				event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
-				event->data.rsz.height = height;
+				event->data.resize.width = (width >= 20) ? width - 20 : 0;;
+				event->data.resize.height = height;
 				break;
 			case KC_N:
-				event->data.rsz.width = width + 20;
-				event->data.rsz.height = height;
+				event->data.resize.width = width + 20;
+				event->data.resize.height = height;
 				break;
 			default:
-				event->data.rsz.width = 0;
-				event->data.rsz.height = 0;
-				break;
-			}
-
+				event->data.resize.width = 0;
+				event->data.resize.height = 0;
+				break;
+			}
+			
+			event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
+			
 			fibril_mutex_unlock(&window_list_mtx);
 			comp_post_event_top(event);
