Example #1
0
/*
   gdk_screen_get_monitor_at_point () doesn't give accurate results
   when the point is off screen, use my own implementation from xfce 3
 */
void
myScreenFindMonitorAtPoint (ScreenInfo *screen_info, gint x, gint y, GdkRectangle *rect)
{
    gint dx, dy, center_x, center_y, num_monitors, i;
    guint32 distsquare, min_distsquare;
    GdkRectangle monitor, nearest_monitor = { G_MAXINT, G_MAXINT, 0, 0 };

    g_return_if_fail (screen_info != NULL);
    g_return_if_fail (rect != NULL);
    g_return_if_fail (GDK_IS_SCREEN (screen_info->gscr));
    TRACE ("entering myScreenFindMonitorAtPoint");

    /* Cache system */
    if ((x >= screen_info->cache_monitor.x) && (x < screen_info->cache_monitor.x + screen_info->cache_monitor.width) &&
        (y >= screen_info->cache_monitor.y) && (y < screen_info->cache_monitor.y + screen_info->cache_monitor.height))
    {
        *rect = screen_info->cache_monitor;
        return;
    }

    min_distsquare = G_MAXUINT32;
    num_monitors = myScreenGetNumMonitors (screen_info);

    for (i = 0; i < num_monitors; i++)
    {
        gint monitor_index;

        monitor_index = myScreenGetMonitorIndex (screen_info, i);
        gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_index, &monitor);

        if ((x >= monitor.x) && (x < (monitor.x + monitor.width)) &&
            (y >= monitor.y) && (y < (monitor.y + monitor.height)))
        {
            screen_info->cache_monitor = monitor;
            *rect = screen_info->cache_monitor;
            return;
        }

        center_x = monitor.x + (monitor.width / 2);
        center_y = monitor.y + (monitor.height / 2);

        dx = x - center_x;
        dy = y - center_y;

        distsquare = (dx * dx) + (dy * dy);

        if (distsquare < min_distsquare)
        {
            min_distsquare = distsquare;
            nearest_monitor = monitor;
        }
    }

    screen_info->cache_monitor = nearest_monitor;
    *rect = screen_info->cache_monitor;
}
Example #2
0
void
clientInitPosition (Client * c)
{
    ScreenInfo *screen_info;
    Client *c2;
    GdkRectangle rect;
    int full_x, full_y, full_w, full_h, msx, msy;
    gint n_monitors;
    gboolean place;
    gboolean position;

    g_return_if_fail (c != NULL);
    TRACE ("entering clientInitPosition");

    screen_info = c->screen_info;
    msx = 0;
    msy = 0;
    position = (c->size->flags & (PPosition | USPosition));

    n_monitors = myScreenGetNumMonitors (c->screen_info);
    if ((n_monitors > 1) || (screen_info->params->placement_mode == PLACE_MOUSE))
    {
        getMouseXY (screen_info, screen_info->xroot, &msx, &msy);
        myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect);
    }
    else
    {
        gdk_screen_get_monitor_geometry (screen_info->gscr, 0, &rect);
    }
    if (position || (c->type & (WINDOW_TYPE_DONT_PLACE | WINDOW_TYPE_DIALOG)) || clientIsTransient (c))
    {
        if (!position && clientIsTransient (c) && (c2 = clientGetTransient (c)))
        {
            /* Center transient relative to their parent window */
            c->x = c2->x + (c2->width - c->width) / 2;
            c->y = c2->y + (c2->height - c->height) / 2;

            if (n_monitors > 1)
            {
                msx = frameX (c) + (frameWidth (c) / 2);
                msy = frameY (c) + (frameHeight (c) / 2);
                myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect);
            }
        }
        if (CONSTRAINED_WINDOW (c))
        {
            clientKeepVisible (c, n_monitors, &rect);
        }
        place = FALSE;
    }
    else
    {
        place = TRUE;
    }

    full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x);
    full_y = MAX (screen_info->params->xfwm_margins[STRUTS_TOP], rect.y);
    full_w = MIN (screen_info->width - screen_info->params->xfwm_margins[STRUTS_RIGHT],
                  rect.x + rect.width) - full_x;
    full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM],
                  rect.y + rect.height) - full_y;

    /* Adjust size to the widest size available, not covering struts */
    clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);

    /*
       If the windows is smaller than the given ratio of the available screen area,
       or if the window is larger than the screen area or if the given ratio is higher
       than 100% place the window at the center.
       Otherwise, place the window "smartly", using the good old CPU consuming algorithm...
     */
    if (place)
    {
        if ((screen_info->params->placement_ratio >= 100) ||
            (100 * frameWidth(c) * frameHeight(c)) < (screen_info->params->placement_ratio * full_w * full_h))
        {
            if (screen_info->params->placement_mode == PLACE_MOUSE)
            {
                mousePlacement (c, full_x, full_y, full_w, full_h, msx, msy);
            }
            else
            {
                centerPlacement (c, full_x, full_y, full_w, full_h);
            }
        }
        else if ((frameWidth(c) >= full_w) && (frameHeight(c) >= full_h))
        {
            centerPlacement (c, full_x, full_y, full_w, full_h);
        }
        else
        {
            smartPlacement (c, full_x, full_y, full_w, full_h);
        }
    }

    if (c->type & WINDOW_REGULAR_FOCUSABLE)
    {
        clientAutoMaximize (c, full_w, full_h);
    }
}