diff options
author | Olivier Fourdan <fourdan@xfce.org> | 2014-10-11 22:16:15 +0100 |
---|---|---|
committer | Olivier Fourdan <fourdan@xfce.org> | 2014-12-09 19:06:13 +0100 |
commit | 41d20680e6fc9da40560f906e15c1200de8189f2 (patch) | |
tree | f2f638ff110b9ea348e2ee8fce8db046bc2bac33 | |
parent | a07b656055fba9f699520e567f106b5f2b3f196f (diff) | |
download | xfwm4-41d20680e6fc9da40560f906e15c1200de8189f2.tar.gz |
Add support for GTK frame extents
This is required for proper positionning and
resizing of CSD windows from GTK3/GNOME.
Signed-off-by: Olivier Fourdan <fourdan@xfce.org>
-rw-r--r-- | src/client.c | 13 | ||||
-rw-r--r-- | src/client.h | 2 | ||||
-rw-r--r-- | src/display.c | 1 | ||||
-rw-r--r-- | src/display.h | 3 | ||||
-rw-r--r-- | src/events.c | 5 | ||||
-rw-r--r-- | src/frame.c | 106 | ||||
-rw-r--r-- | src/frame.h | 8 | ||||
-rw-r--r-- | src/moveresize.c | 128 | ||||
-rw-r--r-- | src/mypixmap.c | 2 | ||||
-rw-r--r-- | src/netwm.c | 38 | ||||
-rw-r--r-- | src/netwm.h | 1 | ||||
-rw-r--r-- | src/placement.c | 170 | ||||
-rw-r--r-- | src/placement.h | 2 | ||||
-rw-r--r-- | src/settings.c | 6 |
14 files changed, 328 insertions, 157 deletions
diff --git a/src/client.c b/src/client.c index 748426f79..db04561b5 100644 --- a/src/client.c +++ b/src/client.c @@ -1734,6 +1734,9 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture) /* workarea will be updated when shown, no need to worry here */ clientGetNetStruts (c); + c->has_frame_extents = FALSE; + clientGetGtkFrameExtents(c); + /* Once we know the type of window, we can initialize window position */ if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED)) { @@ -1825,8 +1828,11 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture) xfwmPixmapInit (screen_info, &c->appmenu[i]); } - for (i = 0; i < SIDE_TOP; i++) /* Keep SIDE_TOP for later */ + for (i = 0; i < SIDE_COUNT; i++) { + if (i == SIDE_TOP) + continue; /* Keep SIDE_TOP for later */ + xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame, &c->sides[i], NoEventMask, myDisplayGetCursorResize(screen_info->display_info, CORNER_COUNT + i)); @@ -1847,8 +1853,7 @@ clientFrame (DisplayInfo *display_info, Window w, gboolean recapture) xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame, &c->sides[SIDE_TOP], NoEventMask, - myDisplayGetCursorResize(screen_info->display_info, - CORNER_COUNT + SIDE_TOP)); + myDisplayGetCursorResize(screen_info->display_info, CORNER_COUNT + SIDE_TOP)); for (i = 0; i < BUTTON_COUNT; i++) { @@ -3608,7 +3613,7 @@ clientUpdateCursor (Client *c) screen_info = c->screen_info; display_info = screen_info->display_info; - for (i = 0; i <= SIDE_TOP; i++) + for (i = 0; i < SIDE_COUNT; i++) { xfwmWindowSetCursor (&c->sides[i], myDisplayGetCursorResize(display_info, CORNER_COUNT + i)); diff --git a/src/client.h b/src/client.h index e8bc4e3ad..7c5549d81 100644 --- a/src/client.h +++ b/src/client.h @@ -312,6 +312,8 @@ struct _Client unsigned long wm_flags; unsigned long xfwm_flags; gint fullscreen_monitors[4]; + gboolean has_frame_extents; + gint frame_extents[SIDE_COUNT]; /* Termination dialog */ gint dialog_pid; diff --git a/src/display.c b/src/display.c index d6dd89424..5e124d71f 100644 --- a/src/display.c +++ b/src/display.c @@ -75,6 +75,7 @@ myDisplayInitAtoms (DisplayInfo *display_info) { static const char *atom_names[] = { "COMPOSITING_MANAGER", + "_GTK_FRAME_EXTENTS", "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", "KWM_WIN_ICON", "_MOTIF_WM_HINTS", diff --git a/src/display.h b/src/display.h index 2ec899385..a058f691b 100644 --- a/src/display.h +++ b/src/display.h @@ -109,8 +109,8 @@ enum { SIDE_LEFT = 0, SIDE_RIGHT, - SIDE_BOTTOM, SIDE_TOP, + SIDE_BOTTOM, SIDE_COUNT }; #define NO_HANDLE -1 @@ -170,6 +170,7 @@ enum enum { COMPOSITING_MANAGER = 0, + GTK_FRAME_EXTENTS, KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR, KWM_WIN_ICON, MOTIF_WM_HINTS, diff --git a/src/events.c b/src/events.c index ccdb2a52c..54d4d9262 100644 --- a/src/events.c +++ b/src/events.c @@ -1905,6 +1905,11 @@ handlePropertyNotify (DisplayInfo *display_info, XPropertyEvent * ev) { clientUpdateIcon (c); } + else if (ev->atom == GTK_FRAME_EXTENTS) + { + TRACE ("client \"%s\" (0x%lx) has received a GTK_FRAME_EXTENTS notify", c->name, c->window); + clientGetGtkFrameExtents (c); + } #ifdef HAVE_STARTUP_NOTIFICATION else if (ev->atom == display_info->atoms[NET_STARTUP_ID]) { diff --git a/src/frame.c b/src/frame.c index 7f4cbd31c..4da599af8 100644 --- a/src/frame.c +++ b/src/frame.c @@ -210,6 +210,112 @@ frameHeight (Client * c) return c->height; } +int +frameExtentLeft (Client * c) +{ + TRACE ("entering frameExtentLeft"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return -c->frame_extents[SIDE_LEFT]; + } + return frameLeft(c); +} + +int +frameExtentRight (Client * c) +{ + TRACE ("entering frameExtentRight"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return -c->frame_extents[SIDE_RIGHT]; + } + return frameRight(c); +} + +int +frameExtentTop (Client * c) +{ + TRACE ("entering frameExtentTop"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return -c->frame_extents[SIDE_TOP]; + } + return frameTop(c); +} + +int +frameExtentBottom (Client * c) +{ + TRACE ("entering frameExtentBottom"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return -c->frame_extents[SIDE_BOTTOM]; + } + return frameBottom(c); +} + +int +frameExtentX (Client * c) +{ + TRACE ("entering frameExtentX"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return c->x + c->frame_extents[SIDE_LEFT]; + } + return frameX(c); +} + +int +frameExtentY (Client * c) +{ + TRACE ("entering frameExtentY"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return c->y + c->frame_extents[SIDE_TOP]; + } + return frameY(c); +} + +int +frameExtentWidth (Client * c) +{ + TRACE ("entering frameExtentWidth"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return MAX (0, c->width - c->frame_extents[SIDE_LEFT] + - c->frame_extents[SIDE_RIGHT]); + } + return frameWidth(c); +} + +int +frameExtentHeight (Client * c) +{ + TRACE ("entering frameExtentHeight"); + + g_return_val_if_fail (c != NULL, 0); + if (c->has_frame_extents) + { + return MAX (0, c->height - c->frame_extents[SIDE_TOP] + - c->frame_extents[SIDE_BOTTOM]); + } + return frameHeight(c); +} + static int frameTopLeftWidth (Client * c, int state) { diff --git a/src/frame.h b/src/frame.h index 9e40eef19..6f34304f9 100644 --- a/src/frame.h +++ b/src/frame.h @@ -44,6 +44,14 @@ int frameX (Client *); int frameY (Client *); int frameWidth (Client *); int frameHeight (Client *); +int frameExtentLeft (Client *); +int frameExtentRight (Client *); +int frameExtentTop (Client *); +int frameExtentBottom (Client *); +int frameExtentX (Client *); +int frameExtentY (Client *); +int frameExtentWidth (Client *); +int frameExtentHeight (Client *); void frameSetShapeInput (Client *); void frameClearQueueDraw (Client *); void frameQueueDraw (Client *, diff --git a/src/moveresize.c b/src/moveresize.c index aa602624b..af1900d7c 100644 --- a/src/moveresize.c +++ b/src/moveresize.c @@ -180,40 +180,40 @@ clientSetHandle(MoveResizeData *passdata, int handle) switch (handle) { case CORNER_BOTTOM_LEFT: - px = frameX (c) + frameLeft(c) / 2; - py = frameY (c) + frameHeight (c) - frameBottom(c) / 2; + px = frameExtentX (c) + frameExtentLeft(c) / 2; + py = frameExtentY (c) + frameExtentHeight (c) - frameExtentBottom(c) / 2; break; case CORNER_BOTTOM_RIGHT: - px = frameX (c) + frameWidth (c) - frameRight(c) / 2; - py = frameY (c) + frameHeight (c) - frameBottom(c) / 2; + px = frameExtentX (c) + frameExtentWidth (c) - frameExtentRight(c) / 2; + py = frameExtentY (c) + frameExtentHeight (c) - frameExtentBottom(c) / 2; break; case CORNER_TOP_LEFT: - px = frameX (c) + frameLeft(c) / 2; - py = frameY (c); + px = frameExtentX (c) + frameExtentLeft(c) / 2; + py = frameExtentY (c); break; case CORNER_TOP_RIGHT: - px = frameX (c) + frameWidth (c) - frameRight(c) / 2; - py = frameY (c); + px = frameExtentX (c) + frameExtentWidth (c) - frameExtentRight(c) / 2; + py = frameExtentY (c); break; case CORNER_COUNT + SIDE_LEFT: - px = frameX (c) + frameLeft(c) / 2; - py = frameY (c) + frameHeight (c) / 2; + px = frameExtentX (c) + frameExtentLeft(c) / 2; + py = frameExtentY (c) + frameExtentHeight (c) / 2; break; case CORNER_COUNT + SIDE_RIGHT: - px = frameX (c) + frameWidth (c) - frameRight(c) / 2; - py = frameY (c) + frameHeight (c) / 2; + px = frameExtentX (c) + frameExtentWidth (c) - frameExtentRight(c) / 2; + py = frameExtentY (c) + frameExtentHeight (c) / 2; break; case CORNER_COUNT + SIDE_TOP: - px = frameX (c) + frameWidth (c) / 2; - py = frameY (c); + px = frameExtentX (c) + frameExtentWidth (c) / 2; + py = frameExtentY (c); break; case CORNER_COUNT + SIDE_BOTTOM: - px = frameX (c) + frameWidth (c) / 2; - py = frameY (c) + frameHeight (c) - frameBottom(c) / 2; + px = frameExtentX (c) + frameExtentWidth (c) / 2; + py = frameExtentY (c) + frameExtentHeight (c) - frameExtentBottom(c) / 2; break; default: - px = frameX (c) + frameWidth (c) / 2; - py = frameY (c) + frameHeight (c) / 2; + px = frameExtentX (c) + frameExtentWidth (c) / 2; + py = frameExtentY (c) + frameExtentHeight (c) / 2; break; } @@ -222,8 +222,8 @@ clientSetHandle(MoveResizeData *passdata, int handle) passdata->handle = handle; passdata->mx = px; passdata->my = py; - passdata->px = passdata->mx - frameX (c); - passdata->py = passdata->my - frameY (c); + passdata->px = passdata->mx - frameExtentX (c); + passdata->py = passdata->my - frameExtentY (c); passdata->ox = c->x; passdata->oy = c->y; passdata->ow = c->width; @@ -320,8 +320,8 @@ clientDrawOutline (Client * c) { TRACE ("entering clientDrawOutline"); - XDrawRectangle (clientGetXDisplay (c), c->screen_info->xroot, c->screen_info->box_gc, frameX (c), frameY (c), - frameWidth (c) - 1, frameHeight (c) - 1); + XDrawRectangle (clientGetXDisplay (c), c->screen_info->xroot, c->screen_info->box_gc, frameExtentX (c), frameExtentY (c), + frameExtentWidth (c) - 1, frameExtentHeight (c) - 1); if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER) &&!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN | CLIENT_FLAG_SHADED)) { @@ -369,15 +369,15 @@ clientFindClosestEdgeX (Client *c, int edge_pos) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)))) { - if (clientCheckOverlap (c->y - frameTop (c) - 1, c->y + c->height + frameBottom (c) + 1, c2->y - frameTop (c) - 1, c2->y + c2->height + frameBottom (c) + 1)) + if (clientCheckOverlap (c->y - frameExtentTop (c) - 1, c->y + c->height + frameExtentBottom (c) + 1, c2->y - frameExtentTop (c) - 1, c2->y + c2->height + frameExtentBottom (c) + 1)) { - if (abs (c2->x - frameLeft (c2) - edge_pos) < abs (closest - edge_pos)) + if (abs (c2->x - frameExtentLeft (c2) - edge_pos) < abs (closest - edge_pos)) { - closest = c2->x - frameLeft (c2); + closest = c2->x - frameExtentLeft (c2); } - if (abs ((c2->x + c2->width) + frameRight (c2) - edge_pos) < abs (closest - edge_pos)) + if (abs ((c2->x + c2->width) + frameExtentRight (c2) - edge_pos) < abs (closest - edge_pos)) { - closest = (c2->x + c2->width) + frameRight (c2); + closest = (c2->x + c2->width) + frameExtentRight (c2); } } } @@ -416,15 +416,15 @@ clientFindClosestEdgeY (Client *c, int edge_pos) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)))) { - if (clientCheckOverlap (c->x - frameLeft (c) - 1, c->x + c->width + frameRight (c) + 1, c2->x - frameLeft (c) - 1, c2->x + c2->width + frameRight (c) + 1)) + if (clientCheckOverlap (c->x - frameExtentLeft (c) - 1, c->x + c->width + frameExtentRight (c) + 1, c2->x - frameExtentLeft (c) - 1, c2->x + c2->width + frameExtentRight (c) + 1)) { - if (abs (c2->y - frameTop(c2) - edge_pos) < abs (closest - edge_pos)) + if (abs (c2->y - frameExtentTop(c2) - edge_pos) < abs (closest - edge_pos)) { - closest = c2->y - frameTop (c2); + closest = c2->y - frameExtentTop (c2); } - if (abs ((c2->y + c2->height) + frameBottom (c2) - edge_pos) < abs (closest - edge_pos)) + if (abs ((c2->y + c2->height) + frameExtentBottom (c2) - edge_pos) < abs (closest - edge_pos)) { - closest = (c2->y + c2->height) + frameBottom (c2); + closest = (c2->y + c2->height) + frameExtentBottom (c2); } } } @@ -462,12 +462,12 @@ clientSnapPosition (Client * c, int prev_x, int prev_y) best_delta_x = screen_info->params->snap_width + 1; best_delta_y = screen_info->params->snap_width + 1; - frame_x = frameX (c); - frame_y = frameY (c); - frame_height = frameHeight (c); - frame_width = frameWidth (c); - frame_top = frameTop (c); - frame_left = frameLeft (c); + frame_x = frameExtentX (c); + frame_y = frameExtentY (c); + frame_height = frameExtentHeight (c); + frame_width = frameExtentWidth (c); + frame_top = frameExtentTop (c); + frame_left = frameExtentLeft (c); cx = frame_x + (frame_width / 2); cy = frame_y + (frame_height / 2); @@ -529,10 +529,10 @@ clientSnapPosition (Client * c, int prev_x, int prev_y) && FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)))) { - c_frame_x1 = frameX (c2); - c_frame_x2 = c_frame_x1 + frameWidth (c2); - c_frame_y1 = frameY (c2); - c_frame_y2 = c_frame_y1 + frameHeight (c2); + c_frame_x1 = frameExtentX (c2); + c_frame_x2 = c_frame_x1 + frameExtentWidth (c2); + c_frame_y1 = frameExtentY (c2); + c_frame_y2 = c_frame_y1 + frameExtentHeight (c2); if ((c_frame_y1 <= frame_y2) && (c_frame_y2 >= frame_y)) { @@ -958,8 +958,8 @@ clientMoveEventFilter (XEvent * xevent, gpointer data) /* to keep the distance from the edges of the window proportional. */ double xratio, yratio; - xratio = (xevent->xmotion.x_root - frameX (c)) / (double) frameWidth (c); - yratio = (xevent->xmotion.y_root - frameY (c)) / (double) frameHeight (c); + xratio = (xevent->xmotion.x_root - frameExtentX (c)) / (double) frameExtentWidth (c); + yratio = (xevent->xmotion.y_root - frameExtentY (c)) / (double) frameExtentHeight (c); if (FLAG_TEST_ALL(c->flags, CLIENT_FLAG_MAXIMIZED)) { @@ -970,17 +970,17 @@ clientMoveEventFilter (XEvent * xevent, gpointer data) passdata->move_resized = TRUE; passdata->ox = c->x; - passdata->mx = frameX (c) + passdata->px; - if ((passdata->mx < frameX (c)) || (passdata->mx > frameX (c) + frameWidth (c))) + passdata->mx = frameExtentX (c) + passdata->px; + if ((passdata->mx < frameExtentX (c)) || (passdata->mx > frameExtentX (c) + frameExtentWidth (c))) { - passdata->mx = CLAMP(frameX (c) + frameWidth (c) * xratio, frameX (c), frameX (c) + frameWidth (c)); + passdata->mx = CLAMP(frameExtentX (c) + frameExtentWidth (c) * xratio, frameExtentX (c), frameExtentX (c) + frameExtentWidth (c)); } passdata->oy = c->y; - passdata->my = frameY (c) + passdata->py; - if ((passdata->my < frameY (c)) || (passdata->my > frameY (c) + frameHeight (c))) + passdata->my = frameExtentY (c) + passdata->py; + if ((passdata->my < frameExtentY (c)) || (passdata->my > frameExtentY (c) + frameExtentHeight (c))) { - passdata->my = CLAMP(frameY (c) + frameHeight (c) * yratio, frameY (c), frameY (c) + frameHeight (c)); + passdata->my = CLAMP(frameExtentY (c) + frameExtentHeight (c) * yratio, frameExtentY (c), frameExtentY (c) + frameExtentHeight (c)); } configure_flags = CFG_FORCE_REDRAW; @@ -1117,8 +1117,8 @@ clientMove (Client * c, XEvent * ev) passdata.button = ev->xbutton.button; passdata.mx = ev->xbutton.x_root; passdata.my = ev->xbutton.y_root; - passdata.px = passdata.mx - frameX (c); - passdata.py = passdata.my - frameY (c); + passdata.px = passdata.mx - frameExtentX (c); + passdata.py = passdata.my - frameExtentY (c); } else { @@ -1313,11 +1313,11 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) */ resizing = FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING); - frame_x = frameX (c); - frame_y = frameY (c); - frame_height = frameHeight (c); - frame_width = frameWidth (c); - frame_top = frameTop (c); + frame_x = frameExtentX (c); + frame_y = frameExtentY (c); + frame_height = frameExtentHeight (c); + frame_width = frameExtentWidth (c); + frame_top = frameExtentTop (c); min_visible = MAX (frame_top, CLIENT_MIN_VISIBLE); cx = frame_x + (frame_width / 2); @@ -1489,7 +1489,7 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) c->width = passdata->ow + (xevent->xmotion.x_root - passdata->mx); /* Attempt to snap the right edge to something. -Cliff */ - c->width = clientFindClosestEdgeX (c, c->x + c->width + frameRight (c)) - c->x - frameRight (c); + c->width = clientFindClosestEdgeX (c, c->x + c->width + frameExtentRight (c)) - c->x - frameExtentRight (c); } if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)) @@ -1503,7 +1503,7 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) c->height = passdata->oh + (xevent->xmotion.y_root - passdata->my); /* Attempt to snap the bottom edge to something. -Cliff */ - c->height = clientFindClosestEdgeY (c, c->y + c->height + frameBottom (c)) - c->y - frameBottom (c); + c->height = clientFindClosestEdgeY (c, c->y + c->height + frameExtentBottom (c)) - c->y - frameExtentBottom (c); } } clientConstrainRatio (c, passdata->handle); @@ -1515,10 +1515,10 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) /* Snap the left edge to something. -Cliff */ right_edge = c->x + c->width; - c->x = clientFindClosestEdgeX (c, c->x - frameLeft (c)) + frameLeft (c); + c->x = clientFindClosestEdgeX (c, c->x - frameExtentLeft (c)) + frameExtentLeft (c); c->width = right_edge - c->x; - frame_x = frameX (c); + frame_x = frameExtentX (c); } clientSetHeight (c, c->height, FALSE); @@ -1528,16 +1528,16 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) /* Snap the top edge to something. -Cliff */ bottom_edge = c->y + c->height; - c->y = clientFindClosestEdgeY (c, c->y - frameTop (c)) + frameTop (c); + c->y = clientFindClosestEdgeY (c, c->y - frameExtentTop (c)) + frameExtentTop (c); c->height = bottom_edge - c->y; - frame_y = frameY (c); + frame_y = frameExtentY (c); } if (move_top) { if ((c->y > MAX (disp_max_y - min_visible, screen_info->height - screen_info->margins [STRUTS_BOTTOM] - min_visible)) - || (!clientCkeckTitle (c) && (frame_y < screen_info->margins [STRUTS_TOP]))) + || (!clientCheckTitle (c) && (frame_y < screen_info->margins [STRUTS_TOP]))) { temp = c->y + c->height; c->y = CLAMP (c->y, screen_info->margins [STRUTS_TOP] + frame_top, diff --git a/src/mypixmap.c b/src/mypixmap.c index bfec217a5..97e670fba 100644 --- a/src/mypixmap.c +++ b/src/mypixmap.c @@ -939,7 +939,7 @@ xfwmPixmapLoad (ScreenInfo * screen_info, xfwmPixmap * pm, const gchar * dir, co gchar *filexpm; GdkPixbuf *pixbuf; - TRACE ("entering xfwmPixmapLoad"); + TRACE ("entering xfwmPixmapLoad(%s)", file); g_return_val_if_fail (pm != NULL, FALSE); g_return_val_if_fail (dir != NULL, FALSE); diff --git a/src/netwm.c b/src/netwm.c index de4b0d690..66e641ff9 100644 --- a/src/netwm.c +++ b/src/netwm.c @@ -1590,3 +1590,41 @@ clientRemoveUserTimeWin (Client * c) XSelectInput (display_info->dpy, c->user_time_win, NoEventMask); } } + +gboolean +clientGetGtkFrameExtents (Client * c) +{ + ScreenInfo *screen_info; + DisplayInfo *display_info; + gulong *extents; + int nitems; + int i; + + g_return_val_if_fail (c != NULL, FALSE); + TRACE ("entering clientGetGtkFrameExtents for \"%s\" (0x%lx)", c->name, c->window); + + screen_info = c->screen_info; + display_info = screen_info->display_info; + c->has_frame_extents = FALSE; + extents = NULL; + + if (getCardinalList (display_info, c->window, GTK_FRAME_EXTENTS, &extents, &nitems)) + { + if (nitems == SIDE_COUNT) + { + c->has_frame_extents = TRUE; + for (i = 0; i < SIDE_COUNT; i++) + { + c->frame_extents[i] = (int) extents[i]; + } + } + } + + if (extents) + { + XFree (extents); + } + + return c->has_frame_extents; +} + diff --git a/src/netwm.h b/src/netwm.h index 5156c1a36..ed266e335 100644 --- a/src/netwm.h +++ b/src/netwm.h @@ -68,5 +68,6 @@ void clientReceiveNetWMPong (ScreenInfo *, gboolean clientGetUserTime (Client *); void clientAddUserTimeWin (Client *); void clientRemoveUserTimeWin (Client *); +gboolean clientGetGtkFrameExtents (Client *); #endif /* INC_NETWM_H */ diff --git a/src/placement.c b/src/placement.c index 1aba248f9..d76c95610 100644 --- a/src/placement.c +++ b/src/placement.c @@ -160,17 +160,17 @@ clientMaxSpace (ScreenInfo *screen_info, int *x, int *y, int *w, int *h) } gboolean -clientCkeckTitle (Client * c) +clientCheckTitle (Client * c) { Client *c2; ScreenInfo *screen_info; guint i; gint frame_x, frame_y, frame_width, frame_top; - frame_x = frameX (c); - frame_y = frameY (c); - frame_width = frameWidth (c); - frame_top = frameTop (c); + frame_x = frameExtentX (c); + frame_y = frameExtentY (c); + frame_width = frameExtentWidth (c); + frame_top = frameExtentTop (c); /* Struts and other partial struts */ screen_info = c->screen_info; @@ -214,12 +214,12 @@ clientConstrainPos (Client * c, gboolean show_full) TRACE ("client \"%s\" (0x%lx)", c->name, c->window); /* We use a bunch of local vars to reduce the overhead of calling other functions all the time */ - frame_x = frameX (c); - frame_y = frameY (c); - frame_height = frameHeight (c); - frame_width = frameWidth (c); - frame_top = frameTop (c); - frame_left = frameLeft (c); + frame_x = frameExtentX (c); + frame_y = frameExtentY (c); + frame_height = frameExtentHeight (c); + frame_width = frameExtentWidth (c); + frame_top = frameExtentTop (c); + frame_left = frameExtentLeft (c); frame_visible = (frame_top ? frame_top : frame_height); min_visible = MAX (frame_top, CLIENT_MIN_VISIBLE); ret = 0; @@ -263,7 +263,7 @@ clientConstrainPos (Client * c, gboolean show_full) screen_width)) { c->x = screen_width - c2->struts[STRUTS_RIGHT] - frame_width + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } } @@ -277,7 +277,7 @@ clientConstrainPos (Client * c, gboolean show_full) screen_height)) { c->y = screen_height - c2->struts[STRUTS_BOTTOM] - frame_height + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } @@ -288,25 +288,25 @@ clientConstrainPos (Client * c, gboolean show_full) if (frame_x + frame_width >= disp_max_x) { c->x = disp_max_x - frame_width + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } if (frame_x <= disp_x) { c->x = disp_x + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_LEFT; } if (frame_y + frame_height >= disp_max_y) { c->y = disp_max_y - frame_height + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } if (frame_y <= disp_y) { c->y = disp_y + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_TOP; } @@ -324,7 +324,7 @@ clientConstrainPos (Client * c, gboolean show_full) 0, c2->struts[STRUTS_LEFT])) { c->x = c2->struts[STRUTS_LEFT] + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_LEFT; } } @@ -339,7 +339,7 @@ clientConstrainPos (Client * c, gboolean show_full) 0, c2->struts[STRUTS_TOP])) { c->y = c2->struts[STRUTS_TOP] + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_TOP; } } @@ -351,31 +351,31 @@ clientConstrainPos (Client * c, gboolean show_full) if (frame_x + frame_width <= disp_x + min_visible) { c->x = disp_x + min_visible - frame_width + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_LEFT; } if (frame_x + min_visible >= disp_max_x) { c->x = disp_max_x - min_visible + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } if (frame_y + frame_height <= disp_y + min_visible) { c->y = disp_y + min_visible - frame_height + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_TOP; } if (frame_y + min_visible >= disp_max_y) { c->y = disp_max_y - min_visible + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } if ((frame_y <= disp_y) && (frame_y >= disp_y - frame_top)) { c->y = disp_y + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_TOP; } /* Struts and other partial struts */ @@ -392,7 +392,7 @@ clientConstrainPos (Client * c, gboolean show_full) if (frame_x >= screen_width - c2->struts[STRUTS_RIGHT] - min_visible) { c->x = screen_width - c2->struts[STRUTS_RIGHT] - min_visible + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_RIGHT; } } @@ -404,7 +404,7 @@ clientConstrainPos (Client * c, gboolean show_full) if (frame_x + frame_width <= c2->struts[STRUTS_LEFT] + min_visible) { c->x = c2->struts[STRUTS_LEFT] + min_visible - frame_width + frame_left; - frame_x = frameX (c); + frame_x = frameExtentX (c); ret |= CLIENT_CONSTRAINED_LEFT; } } @@ -416,7 +416,7 @@ clientConstrainPos (Client * c, gboolean show_full) if (frame_y >= screen_height - c2->struts[STRUTS_BOTTOM] - min_visible) { c->y = screen_height - c2->struts[STRUTS_BOTTOM] - min_visible + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_BOTTOM; } } @@ -428,13 +428,13 @@ clientConstrainPos (Client * c, gboolean show_full) if (segment_overlap (frame_y, frame_y + frame_visible, 0, c2->struts[STRUTS_TOP])) { c->y = c2->struts[STRUTS_TOP] + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_TOP; } if (frame_y + frame_height <= c2->struts[STRUTS_TOP] + min_visible) { c->y = c2->struts[STRUTS_TOP] + min_visible - frame_height + frame_top; - frame_y = frameY (c); + frame_y = frameExtentY (c); ret |= CLIENT_CONSTRAINED_TOP; } } @@ -514,20 +514,20 @@ clientAutoMaximize (Client * c, int full_w, int full_h) } if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) && - (frameWidth (c) >= full_w)) + (frameExtentWidth (c) >= full_w)) { TRACE ("The application \"%s\" has requested a window width " "(%u) equal or larger than the actual width available in the workspace (%u), " - "the window will be maximized horizontally.", c->name, frameWidth (c), full_w); + "the window will be maximized horizontally.", c->name, frameExtentWidth (c), full_w); FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ); } if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) && - (frameHeight (c) >= full_h)) + (frameExtentHeight (c) >= full_h)) { TRACE ("The application \"%s\" has requested a window height " "(%u) equal or larger than the actual height available in the workspace (%u), " - "the window will be maximized vertically.", c->name, frameHeight (c), full_h); + "the window will be maximized vertically.", c->name, frameExtentHeight (c), full_h); FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT); } } @@ -548,18 +548,18 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) TRACE ("entering smartPlacement"); screen_info = c->screen_info; - frame_height = frameHeight (c); - frame_width = frameWidth (c); - frame_left = frameLeft(c); - frame_top = frameTop (c); + frame_height = frameExtentHeight (c); + frame_width = frameExtentWidth (c); + frame_left = frameExtentLeft(c); + frame_top = frameExtentTop (c); /* max coordinates (bottom-right) */ - xmax = full_x + full_w - c->width - frameRight (c); - ymax = full_y + full_h - c->height - frameBottom (c); + xmax = full_x + full_w - c->width - frameExtentRight (c); + ymax = full_y + full_h - c->height - frameExtentBottom (c); /* min coordinates (top-left) */ - xmin = full_x + frameLeft (c); - ymin = full_y + frameTop (c); + xmin = full_x + frameExtentLeft (c); + ymin = full_y + frameExtentTop (c); /* start with worst-case position at top-left */ best_overlaps = G_MAXFLOAT; @@ -594,8 +594,8 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) && (c->win_workspace == c2->win_workspace) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)) { - c2_x = frameX (c2); - c2_frame_width = frameWidth (c2); + c2_x = frameExtentX (c2); + c2_frame_width = frameExtentWidth (c2); if (c2_x >= full_x + full_w || c2_x + c2_frame_width < full_x) { @@ -603,8 +603,8 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) continue; } - c2_y = frameY (c2); - c2_frame_height = frameHeight (c2); + c2_y = frameExtentY (c2); + c2_frame_height = frameExtentHeight (c2); if (c2_y >= full_y + full_h || c2_y + c2_frame_height < full_y) { @@ -632,7 +632,7 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) if (c2_next_test_x < next_test_x && c2_next_test_x > test_x) { - /* set new optimal next x step poistion */ + /* set new optimal next x step position */ next_test_x = c2_next_test_x; } @@ -649,7 +649,7 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) if (c2_next_test_y < next_test_y && c2_next_test_y > test_y) { - /* set new optimal next y step poistion */ + /* set new optimal next y step position */ next_test_y = c2_next_test_y; } } @@ -676,7 +676,7 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) if (G_LIKELY (next_test_x != G_MAXINT)) { - test_x = next_test_x + frameLeft (c); + test_x = MAX (next_test_x, next_test_x + frameExtentLeft (c)); if (test_x > xmax) { /* always clamp on the monitor */ @@ -688,11 +688,11 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) test_x++; } } - while (test_x <= xmax); + while (test_x < xmax); if (G_LIKELY (next_test_y != G_MAXINT)) { - test_y = next_test_y + frameTop (c); + test_y = MAX (next_test_y, next_test_y + frameExtentTop (c)); if (test_y > ymax) { /* always clamp on the monitor */ @@ -704,7 +704,7 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) test_y++; } } - while (test_y <= ymax); + while (test_y < ymax); found_best: @@ -720,8 +720,8 @@ centerPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) g_return_if_fail (c != NULL); TRACE ("entering centerPlacement"); - c->x = MAX (full_x + frameLeft(c) + (full_w - frameWidth(c)) / 2, full_x + frameLeft(c)); - c->y = MAX (full_y + frameTop(c) + (full_h - frameHeight(c)) / 2, full_y + frameTop(c)); + c->x = MAX (full_x + frameExtentLeft(c) + (full_w - frameExtentWidth(c)) / 2, full_x + frameExtentLeft(c)); + c->y = MAX (full_y + frameExtentTop(c) + (full_h - frameExtentHeight(c)) / 2, full_y + frameExtentTop(c)); } static void @@ -730,14 +730,14 @@ mousePlacement (Client * c, int full_x, int full_y, int full_w, int full_h, int g_return_if_fail (c != NULL); TRACE ("entering mousePlacement"); - c->x = mx + frameLeft(c) - frameWidth(c) / 2; - c->y = my + frameTop(c) - frameHeight(c) / 2; + c->x = mx + frameExtentLeft(c) - frameExtentWidth(c) / 2; + c->y = my + frameExtentTop(c) - frameExtentHeight(c) / 2; - c->x = MIN (c->x, full_x + full_w - frameWidth(c) + frameLeft(c)); - c->y = MIN (c->y, full_y + full_h - frameHeight(c) + frameTop(c)); + c->x = MIN (c->x, full_x + full_w - frameExtentWidth(c) + frameExtentLeft(c)); + c->y = MIN (c->y, full_y + full_h - frameExtentHeight(c) + frameExtentTop(c)); - c->x = MAX (c->x, full_x + frameLeft(c)); - c->y = MAX (c->y, full_y + frameTop(c)); + c->x = MAX (c->x, full_x + frameExtentLeft(c)); + c->y = MAX (c->y, full_y + frameExtentTop(c)); } void @@ -779,8 +779,8 @@ clientInitPosition (Client * c) if (n_monitors > 1) { - msx = frameX (c) + (frameWidth (c) / 2); - msy = frameY (c) + (frameHeight (c) / 2); + msx = frameExtentX (c) + (frameExtentWidth (c) / 2); + msy = frameExtentY (c) + (frameExtentHeight (c) / 2); myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect); } } @@ -814,7 +814,7 @@ clientInitPosition (Client * c) if (place) { if ((screen_info->params->placement_ratio >= 100) || - (100 * frameWidth(c) * frameHeight(c)) < (screen_info->params->placement_ratio * full_w * full_h)) + (100 * frameExtentWidth(c) * frameExtentHeight(c)) < (screen_info->params->placement_ratio * full_w * full_h)) { if (screen_info->params->placement_mode == PLACE_MOUSE) { @@ -825,7 +825,7 @@ clientInitPosition (Client * c) centerPlacement (c, full_x, full_y, full_w, full_h); } } - else if ((frameWidth(c) >= full_w) && (frameHeight(c) >= full_h)) + else if ((frameExtentWidth(c) >= full_w) && (frameExtentHeight(c) >= full_h)) { centerPlacement (c, full_x, full_y, full_w, full_h); } @@ -888,16 +888,16 @@ clientFill (Client * c, int fill_type) * check if the neigbour client (c2) is located * east or west of our client. */ - if (segment_overlap (frameY(c), frameY(c) + frameHeight(c), frameY(c2), frameY(c2) + frameHeight(c2))) + if (segment_overlap (frameExtentY(c), frameExtentY(c) + frameExtentHeight(c), frameExtentY(c2), frameExtentY(c2) + frameExtentHeight(c2))) { - if ((frameX(c2) + frameWidth(c2)) <= frameX(c)) + if ((frameExtentX(c2) + frameExtentWidth(c2)) <= frameExtentX(c)) { if (west_neighbour) { /* Check if c2 is closer to the client * then the west neighbour already found */ - if ((frameX(west_neighbour) + frameWidth(west_neighbour)) < (frameX(c2) + frameWidth(c2))) + if ((frameExtentX(west_neighbour) + frameExtentWidth(west_neighbour)) < (frameExtentX(c2) + frameExtentWidth(c2))) { west_neighbour = c2; } @@ -907,14 +907,14 @@ clientFill (Client * c, int fill_type) west_neighbour = c2; } } - if ((frameX(c) + frameWidth(c)) <= frameX(c2)) + if ((frameExtentX(c) + frameExtentWidth(c)) <= frameExtentX(c2)) { /* Check if c2 is closer to the client * then the west neighbour already found */ if (east_neighbour) { - if (frameX(c2) < frameX(east_neighbour)) + if (frameExtentX(c2) < frameExtentX(east_neighbour)) { east_neighbour = c2; } @@ -933,16 +933,16 @@ clientFill (Client * c, int fill_type) /* check if the neigbour client (c2) is located * north or south of our client. */ - if (segment_overlap (frameX(c), frameX(c) + frameWidth(c), frameX(c2), frameX(c2) + frameWidth(c2))) + if (segment_overlap (frameExtentX(c), frameExtentX(c) + frameExtentWidth(c), frameExtentX(c2), frameExtentX(c2) + frameExtentWidth(c2))) { - if ((frameY(c2) + frameHeight(c2)) <= frameY(c)) + if ((frameExtentY(c2) + frameExtentHeight(c2)) <= frameExtentY(c)) { if (north_neighbour) { /* Check if c2 is closer to the client * then the north neighbour already found */ - if ((frameY(north_neighbour) + frameHeight(north_neighbour)) < (frameY(c2) + frameHeight(c2))) + if ((frameExtentY(north_neighbour) + frameExtentHeight(north_neighbour)) < (frameExtentY(c2) + frameExtentHeight(c2))) { north_neighbour = c2; } @@ -952,14 +952,14 @@ clientFill (Client * c, int fill_type) north_neighbour = c2; } } - if ((frameY(c) + frameHeight(c)) <= frameY(c2)) + if ((frameExtentY(c) + frameExtentHeight(c)) <= frameExtentY(c2)) { if (south_neighbour) { /* Check if c2 is closer to the client * then the south neighbour already found */ - if (frameY(c2) < frameY(south_neighbour)) + if (frameExtentY(c2) < frameExtentY(south_neighbour)) { south_neighbour = c2; } @@ -975,10 +975,10 @@ clientFill (Client * c, int fill_type) } /* Compute the largest size available, based on struts, margins and Xinerama layout */ - tmp_x = frameX (c); - tmp_y = frameY (c); - tmp_h = frameHeight (c); - tmp_w = frameWidth (c); + tmp_x = frameExtentX (c); + tmp_y = frameExtentY (c); + tmp_h = frameExtentHeight (c); + tmp_w = frameExtentWidth (c); cx = tmp_x + (tmp_w / 2); cy = tmp_y + (tmp_h / 2); @@ -1015,28 +1015,28 @@ clientFill (Client * c, int fill_type) * If not, resize to the largest size available that you just have computed. */ - wc.x = full_x + frameLeft(c); + wc.x = full_x + frameExtentLeft(c); if (west_neighbour) { - wc.x += MAX (frameX(west_neighbour) + frameWidth(west_neighbour) - full_x, 0); + wc.x += MAX (frameExtentX(west_neighbour) + frameExtentWidth(west_neighbour) - full_x, 0); } - wc.width = full_w - frameRight(c) - (wc.x - full_x); + wc.width = full_w - frameExtentRight(c) - (wc.x - full_x); if (east_neighbour) { - wc.width -= MAX (full_w - (frameX(east_neighbour) - full_x), 0); + wc.width -= MAX (full_w - (frameExtentX(east_neighbour) - full_x), 0); } - wc.y = full_y + frameTop(c); + wc.y = full_y + frameExtentTop(c); if (north_neighbour) { - wc.y += MAX (frameY(north_neighbour) + frameHeight(north_neighbour) - full_y, 0); + wc.y += MAX (frameExtentY(north_neighbour) + frameExtentHeight(north_neighbour) - full_y, 0); } - wc.height = full_h - frameBottom(c) - (wc.y - full_y); + wc.height = full_h - frameExtentBottom(c) - (wc.y - full_y); if (south_neighbour) { - wc.height -= MAX (full_h - (frameY(south_neighbour) - full_y), 0); + wc.height -= MAX (full_h - (frameExtentY(south_neighbour) - full_y), 0); } TRACE ("Fill size request: (%d,%d) %dx%d", wc.x, wc.y, wc.width, wc.height); diff --git a/src/placement.h b/src/placement.h index 3ecd3d504..c1eaa3ba0 100644 --- a/src/placement.h +++ b/src/placement.h @@ -40,7 +40,7 @@ void clientMaxSpace (ScreenInfo *, int *, int *, int *); -gboolean clientCkeckTitle (Client *); +gboolean clientCheckTitle (Client *); unsigned int clientConstrainPos (Client *, gboolean); void clientInitPosition (Client *); diff --git a/src/settings.c b/src/settings.c index 5622ba7b7..1eb98da8d 100644 --- a/src/settings.c +++ b/src/settings.c @@ -309,6 +309,7 @@ loadTheme (ScreenInfo *screen_info, Settings *rc) static const char *side_names[] = { "left", "right", + "top", /* ** unused ** */ "bottom" }; @@ -488,8 +489,11 @@ loadTheme (ScreenInfo *screen_info, Settings *rc) screen_info->white_gc = widget->style->white_gc; g_object_ref (G_OBJECT (widget->style->white_gc)); - for (i = 0; i < SIDE_TOP; i++) /* Keep SIDE_TOP for later */ + for (i = 0; i < SIDE_COUNT; i++) { + if (i == SIDE_TOP) + continue; /* There is no top decoration per se. */ + g_snprintf(imagename, sizeof (imagename), "%s-active", side_names[i]); xfwmPixmapLoad (screen_info, &screen_info->sides[i][ACTIVE], theme, imagename, colsym); |