~ubuntu-branches/ubuntu/precise/xfwm4/precise-updates

« back to all changes in this revision

Viewing changes to src/placement.c

  • Committer: Bazaar Package Importer
  • Author(s): Jérôme Guelfucci, Jérôme Guelfucci, Lionel Le Folgoc
  • Date: 2009-01-30 18:28:59 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20090130182859-1tci3n1f1hhppvc2
Tags: 4.5.99.1-0ubuntu1
[ Jérôme Guelfucci ]
* Merge with Debian Xfce UNRELEASED, remaining Ubuntu changes:
  - debian/xfwm4.1: update bug reporting address (LP instead of Debian BTS).

[ Lionel Le Folgoc ]
* debian/control: use our Vcs-* fields.
* Bugs fixed by this new release:
  - "User interface of focused application is covered by another application's
    new window in Xfce" (LP: #250101)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*      $Id: placement.c 26966 2008-05-17 08:22:17Z olivier $
 
1
/*      $Id$
2
2
 
3
3
        This program is free software; you can redistribute it and/or modify
4
4
        it under the terms of the GNU General Public License as published by
12
12
 
13
13
        You should have received a copy of the GNU General Public License
14
14
        along with this program; if not, write to the Free Software
15
 
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 
 
17
 
        xfwm4    - (c) 2002-2006 Olivier Fourdan
 
15
        Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
 
16
        MA 02110-1301, USA.
 
17
 
 
18
 
 
19
        xfwm4    - (c) 2002-2009 Olivier Fourdan
18
20
 
19
21
 */
20
22
 
21
23
#ifdef HAVE_CONFIG_H
22
 
#include <config.h>
 
24
#include "config.h"
23
25
#endif
24
26
 
25
27
#include <X11/Xlib.h>
36
38
#include "frame.h"
37
39
#include "netwm.h"
38
40
 
39
 
static unsigned long overlapX (int x0, int x1, int tx0, int tx1);
40
 
static unsigned long overlapY (int y0, int y1, int ty0, int ty1);
41
 
static unsigned long overlap (int x0, int y0, int x1, int y1,
42
 
                              int tx0, int ty0, int tx1, int ty1);
43
 
 
44
41
/* Compute rectangle overlap area */
45
42
 
46
43
static unsigned long
47
 
overlapX (int x0, int x1, int tx0, int tx1)
 
44
segment_overlap (int x0, int x1, int tx0, int tx1)
48
45
{
49
46
    if (tx0 > x0)
50
47
    {
62
59
}
63
60
 
64
61
static unsigned long
65
 
overlapY (int y0, int y1, int ty0, int ty1)
66
 
{
67
 
    if (ty0 > y0)
68
 
    {
69
 
        y0 = ty0;
70
 
    }
71
 
    if (ty1 < y1)
72
 
    {
73
 
        y1 = ty1;
74
 
    }
75
 
    if (y1 <= y0)
76
 
    {
77
 
        return 0;
78
 
    }
79
 
    return (y1 - y0);
80
 
}
81
 
 
82
 
static unsigned long
83
62
overlap (int x0, int y0, int x1, int y1, int tx0, int ty0, int tx1, int ty1)
84
63
{
85
64
    /* Compute overlapping box */
86
 
    return (overlapX (x0, x1, tx0, tx1) * overlapY (y0, y1, ty0, ty1));
 
65
    return (segment_overlap (x0, x1, tx0, tx1)
 
66
            * segment_overlap (y0, y1, ty0, ty1));
87
67
}
88
68
 
89
69
static unsigned long
222
202
    int screen_width, screen_height;
223
203
    unsigned int ret;
224
204
    GdkRectangle rect;
225
 
    gint monitor_nbr;
226
205
    gint min_visible;
227
206
 
228
207
    g_return_val_if_fail (c != NULL, 0);
245
224
    cy = frame_y + (frame_height / 2);
246
225
 
247
226
    screen_info = c->screen_info;
248
 
    monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
249
 
    gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
 
227
    myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
250
228
 
251
229
    screen_width = screen_info->width;
252
230
    screen_height = screen_info->height;
273
251
                && (c2 != c))
274
252
            {
275
253
                /* Right */
276
 
                if (overlapY (frame_y, frame_y + frame_height,
 
254
                if (segment_overlap (frame_y, frame_y + frame_height,
277
255
                              c2->struts[STRUTS_RIGHT_START_Y], c2->struts[STRUTS_RIGHT_END_Y]))
278
256
                {
279
 
                    if (overlapX (frame_x, frame_x + frame_width,
 
257
                    if (segment_overlap (frame_x, frame_x + frame_width,
280
258
                                  screen_width - c2->struts[STRUTS_RIGHT],
281
259
                                  screen_width))
282
260
                    {
287
265
                }
288
266
 
289
267
                /* Bottom */
290
 
                if (overlapX (frame_x, frame_x + frame_width,
 
268
                if (segment_overlap (frame_x, frame_x + frame_width,
291
269
                              c2->struts[STRUTS_BOTTOM_START_X], c2->struts[STRUTS_BOTTOM_END_X]))
292
270
                {
293
 
                    if (overlapY (frame_y, frame_y + frame_height,
 
271
                    if (segment_overlap (frame_y, frame_y + frame_height,
294
272
                                  screen_height - c2->struts[STRUTS_BOTTOM],
295
273
                                  screen_height))
296
274
                    {
335
313
                && (c2 != c))
336
314
            {
337
315
                /* Left */
338
 
                if (overlapY (frame_y, frame_y + frame_height,
 
316
                if (segment_overlap (frame_y, frame_y + frame_height,
339
317
                              c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT_END_Y]))
340
318
                {
341
 
                    if (overlapX (frame_x, frame_x + frame_width,
 
319
                    if (segment_overlap (frame_x, frame_x + frame_width,
342
320
                                  0, c2->struts[STRUTS_LEFT]))
343
321
                    {
344
322
                        c->x = c2->struts[STRUTS_LEFT] + frame_left;
348
326
                }
349
327
 
350
328
                /* Top */
351
 
                if (overlapX (frame_x,
 
329
                if (segment_overlap (frame_x,
352
330
                              frame_x + frame_width,
353
331
                              c2->struts[STRUTS_TOP_START_X],
354
332
                              c2->struts[STRUTS_TOP_END_X]))
355
333
                {
356
 
                    if (overlapY (frame_y, frame_y + frame_height,
 
334
                    if (segment_overlap (frame_y, frame_y + frame_height,
357
335
                                  0, c2->struts[STRUTS_TOP]))
358
336
                    {
359
337
                        c->y = c2->struts[STRUTS_TOP] + frame_top;
404
382
                && (c2 != c))
405
383
            {
406
384
                /* Right */
407
 
                if (overlapY (frame_y, frame_y + frame_height,
 
385
                if (segment_overlap (frame_y, frame_y + frame_height,
408
386
                              c2->struts[STRUTS_RIGHT_START_Y], c2->struts[STRUTS_RIGHT_END_Y]))
409
387
                {
410
388
                    if (frame_x >= screen_width - c2->struts[STRUTS_RIGHT] - min_visible)
416
394
                }
417
395
 
418
396
                /* Left */
419
 
                if (overlapY (frame_y, frame_y + frame_height,
 
397
                if (segment_overlap (frame_y, frame_y + frame_height,
420
398
                              c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT_END_Y]))
421
399
                {
422
400
                    if (frame_x + frame_width <= c2->struts[STRUTS_LEFT] + min_visible)
428
406
                }
429
407
 
430
408
                /* Bottom */
431
 
                if (overlapX (frame_x, frame_x + frame_width,
 
409
                if (segment_overlap (frame_x, frame_x + frame_width,
432
410
                              c2->struts[STRUTS_BOTTOM_START_X], c2->struts[STRUTS_BOTTOM_END_X]))
433
411
                {
434
412
                    if (frame_y >= screen_height - c2->struts[STRUTS_BOTTOM] - min_visible)
440
418
                }
441
419
 
442
420
                /* Top */
443
 
                if (overlapX (frame_x, frame_x + frame_width,
 
421
                if (segment_overlap (frame_x, frame_x + frame_width,
444
422
                              c2->struts[STRUTS_TOP_START_X], c2->struts[STRUTS_TOP_END_X]))
445
423
                {
446
 
                    if (overlapY (frame_y, frame_y + frame_visible, 0, c2->struts[STRUTS_TOP]))
 
424
                    if (segment_overlap (frame_y, frame_y + frame_visible, 0, c2->struts[STRUTS_TOP]))
447
425
                    {
448
426
                        c->y = c2->struts[STRUTS_TOP] + frame_top;
449
427
                        frame_y = frameY (c);
470
448
static void
471
449
clientKeepVisible (Client * c, gint n_monitors, GdkRectangle *monitor_rect)
472
450
{
 
451
    ScreenInfo *screen_info;
 
452
    GdkRectangle rect;
 
453
    gboolean centered;
473
454
    int cx, cy;
474
455
    int diff_x, diff_y;
 
456
    int monitor_nbr;
475
457
 
476
458
    g_return_if_fail (c != NULL);
477
459
    TRACE ("entering clientKeepVisible");
479
461
 
480
462
    cx = frameX (c) + (frameWidth (c) / 2);
481
463
    cy = frameY (c) + (frameHeight (c) / 2);
482
 
 
483
 
    /* Translate coodinates to center on physical screen */
484
 
 
485
 
    diff_x = abs (c->size->x - ((c->screen_info->width - c->width) / 2));
486
 
    diff_y = abs (c->size->y - ((c->screen_info->height - c->height) / 2));
487
 
 
488
 
    if (((n_monitors > 1) && (diff_x < 25) && (diff_y < 25)) ||
489
 
        ((frameX (c) == 0) && (frameY (c) == 0) && (c->type & (WINDOW_TYPE_DIALOG))))
 
464
    screen_info = c->screen_info;
 
465
 
 
466
    centered = FALSE;
 
467
    if ((c->size->x == 0) && (c->size->y == 0) && (c->type & (WINDOW_TYPE_DIALOG)))
 
468
    {
 
469
        /* Dialogs that place temselves in (0,0) will be centered */
 
470
        centered = TRUE;
 
471
    }
 
472
    else if (n_monitors > 1)
 
473
    {
 
474
        /* First, check if the window is centered on the whole screen */
 
475
        diff_x = abs (c->size->x - ((c->screen_info->width - c->size->width) / 2));
 
476
        diff_y = abs (c->size->y - ((c->screen_info->height - c->size->height) / 2));
 
477
 
 
478
        monitor_nbr = 0;
 
479
        centered = ((diff_x < 25) && (diff_y < 25));
 
480
 
 
481
        while ((!centered) && (monitor_nbr < n_monitors))
 
482
        {
 
483
            gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
 
484
            diff_x = abs (c->size->x - ((rect.width - c->size->width) / 2));
 
485
            diff_y = abs (c->size->y - ((rect.height - c->size->height) / 2));
 
486
            centered = ((diff_x < 25) && (diff_y < 25));
 
487
            monitor_nbr++;
 
488
        }
 
489
    }
 
490
    if (centered)
490
491
    {
491
492
        /* We consider that the windows is centered on screen,
492
493
         * Thus, will move it so its center on the current
502
503
clientAutoMaximize (Client * c, int full_w, int full_h)
503
504
{
504
505
    if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN) ||
505
 
        FLAG_TEST (c->xfwm_flags, XFWM_FLAG_LEGACY_FULLSCREEN))
 
506
        FLAG_TEST (c->xfwm_flags, XFWM_FLAG_LEGACY_FULLSCREEN) ||
 
507
        !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER))
506
508
    {
507
 
        /* Fullscree nwindows should not be maximized */
 
509
        /*
 
510
         * Fullscreen or undecorated windows should not be
 
511
         * automatically maximized...
 
512
         */
508
513
        return;
509
514
    }
510
515
 
511
516
    if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) &&
512
517
        (frameWidth (c) > full_w))
513
518
    {
 
519
        TRACE ("The application \"%s\" has requested a window width "
 
520
               "(%u) larger than the actual width available in the workspace (%u), "
 
521
               "the window will be maximized horizontally.", c->name, frameWidth (c), full_w);
514
522
        FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
515
523
    }
516
524
 
517
525
    if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) &&
518
526
        (frameHeight (c) > full_h))
519
527
    {
 
528
        TRACE ("The application \"%s\" has requested a window height "
 
529
               "(%u) larger than the actual height available in the workspace (%u), "
 
530
               "the window will be maximized vertically.", c->name, frameHeight (c), full_h);
520
531
        FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
521
532
    }
522
533
}
551
562
    best_x = full_x + frameLeft (c);
552
563
    best_y = full_y + frameTop (c);
553
564
 
554
 
    for (test_y = full_y + frameTop (c); test_y <= ymax;
555
 
        test_y += 8)
 
565
    test_y = full_y + frameTop (c);
 
566
    do
556
567
    {
557
 
        for (test_x = full_x + frameLeft (c);
558
 
            test_x <= xmax; test_x += 8)
 
568
        test_x = full_x + frameLeft (c);
 
569
        do
559
570
        {
560
571
            gfloat count_overlaps = 0.0;
561
572
            TRACE ("analyzing %i clients", screen_info->client_count);
593
604
            {
594
605
                first = FALSE;
595
606
            }
 
607
            test_x += 8;
596
608
        }
 
609
        while (test_x <= xmax);
 
610
        test_y += 8;
597
611
    }
 
612
    while (test_y <= ymax);
 
613
 
598
614
    c->x = best_x;
599
615
    c->y = best_y;
600
616
}
609
625
    c->y = MAX (full_y + frameTop(c) + (full_h - frameHeight(c)) / 2, full_y + frameTop(c));
610
626
}
611
627
 
 
628
static void
 
629
mousePlacement (Client * c, int full_x, int full_y, int full_w, int full_h, int mx, int my)
 
630
{
 
631
    g_return_if_fail (c != NULL);
 
632
    TRACE ("entering centerPlacement");
 
633
 
 
634
    c->x = mx + frameLeft(c) - frameWidth(c) / 2;
 
635
    c->y = my + frameTop(c) - frameHeight(c) / 2;
 
636
 
 
637
    c->x = MIN (c->x, full_x + full_w - frameWidth(c) + frameLeft(c));
 
638
    c->y = MIN (c->y, full_y + full_h - frameHeight(c) + frameTop(c));
 
639
 
 
640
    c->x = MAX (c->x, full_x + frameLeft(c));
 
641
    c->y = MAX (c->y, full_y + frameTop(c));
 
642
}
 
643
 
612
644
void
613
645
clientInitPosition (Client * c)
614
646
{
616
648
    Client *c2;
617
649
    GdkRectangle rect;
618
650
    int full_x, full_y, full_w, full_h, msx, msy;
619
 
    gint monitor_nbr;
620
651
    gint n_monitors;
621
652
    gboolean place;
622
653
    gboolean position;
624
655
    g_return_if_fail (c != NULL);
625
656
    TRACE ("entering clientInitPosition");
626
657
 
627
 
    clientGravitate (c, APPLY);
628
 
 
629
658
    screen_info = c->screen_info;
630
659
    msx = 0;
631
660
    msy = 0;
632
661
    position = (c->size->flags & (PPosition | USPosition));
633
662
 
634
663
    n_monitors = gdk_screen_get_n_monitors (c->screen_info->gscr);
635
 
    monitor_nbr = 0;
636
 
    if (n_monitors > 1)
 
664
    if ((n_monitors > 1) || (screen_info->params->placement_mode == PLACE_MOUSE))
637
665
    {
638
666
        getMouseXY (screen_info, screen_info->xroot, &msx, &msy);
639
 
        monitor_nbr = find_monitor_at_point (screen_info->gscr, msx, msy);
640
 
    }
641
 
    gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
642
 
 
 
667
        myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect);
 
668
    }
 
669
    else
 
670
    {
 
671
        gdk_screen_get_monitor_geometry (screen_info->gscr, 0, &rect);
 
672
    }
643
673
    if (position || (c->type & (WINDOW_TYPE_DONT_PLACE | WINDOW_TYPE_DIALOG)) || clientIsTransient (c))
644
674
    {
645
675
        if (!position && clientIsTransient (c) && (c2 = clientGetTransient (c)))
652
682
            {
653
683
                msx = frameX (c) + (frameWidth (c) / 2);
654
684
                msy = frameY (c) + (frameHeight (c) / 2);
655
 
                monitor_nbr = find_monitor_at_point (screen_info->gscr, msx, msy);
656
 
                gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
 
685
                myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect);
657
686
            }
658
687
        }
659
688
        if (CONSTRAINED_WINDOW (c))
685
714
     */
686
715
    if (place)
687
716
    {
688
 
        if ((screen_info->params->placement_ratio > 100) ||
689
 
            ((frameWidth(c) >= full_w) && (frameHeight(c) >= full_h)) ||
 
717
        if ((screen_info->params->placement_ratio >= 100) ||
690
718
            (100 * frameWidth(c) * frameHeight(c)) < (screen_info->params->placement_ratio * full_w * full_h))
691
719
        {
 
720
            if (screen_info->params->placement_mode == PLACE_MOUSE)
 
721
            {
 
722
                mousePlacement (c, full_x, full_y, full_w, full_h, msx, msy);
 
723
            }
 
724
            else
 
725
            {
 
726
                centerPlacement (c, full_x, full_y, full_w, full_h);
 
727
            }
 
728
        }
 
729
        else if ((frameWidth(c) >= full_w) && (frameHeight(c) >= full_h))
 
730
        {
692
731
            centerPlacement (c, full_x, full_y, full_w, full_h);
693
732
        }
694
733
        else
702
741
        clientAutoMaximize (c, full_w, full_h);
703
742
    }
704
743
}
 
744
 
 
745
 
 
746
void
 
747
clientFill (Client * c, int fill_type)
 
748
{
 
749
    ScreenInfo *screen_info;
 
750
    DisplayInfo *display_info;
 
751
    Client *east_neighbour;
 
752
    Client *west_neighbour;
 
753
    Client *north_neighbour;
 
754
    Client *south_neighbour;
 
755
    Client *c2;
 
756
    GdkRectangle rect;
 
757
    XWindowChanges wc;
 
758
    unsigned short mask;
 
759
    int i, cx, cy, full_x, full_y, full_w, full_h;
 
760
    int tmp_x, tmp_y, tmp_w, tmp_h;
 
761
 
 
762
    g_return_if_fail (c != NULL);
 
763
 
 
764
    if (!CLIENT_CAN_FILL_WINDOW (c))
 
765
    {
 
766
        return;
 
767
    }
 
768
 
 
769
    screen_info = c->screen_info;
 
770
    display_info = screen_info->display_info;
 
771
    mask = 0;
 
772
    east_neighbour = NULL;
 
773
    west_neighbour = NULL;
 
774
    north_neighbour = NULL;
 
775
    south_neighbour = NULL;
 
776
 
 
777
    for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
 
778
    {
 
779
 
 
780
        /* Filter out all windows which are not visible, or not on the same layer
 
781
         * as well as the client window itself
 
782
         */
 
783
        if ((c != c2) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2->win_layer == c->win_layer))
 
784
        {
 
785
            /* Fill horizontally */
 
786
            if (fill_type & CLIENT_FILL_HORIZ)
 
787
            {
 
788
                /*
 
789
                 * check if the neigbour client (c2) is located
 
790
                 * east or west of our client.
 
791
                 */
 
792
                if (segment_overlap (frameY(c), frameY(c) + frameHeight(c), frameY(c2), frameY(c2) + frameHeight(c2)))
 
793
                {
 
794
                    if ((frameX(c2) + frameWidth(c2)) < frameX(c))
 
795
                    {
 
796
                        if (east_neighbour)
 
797
                        {
 
798
                            /* Check if c2 is closer to the client
 
799
                             * then the east neighbour already found
 
800
                             */
 
801
                            if ((frameX(east_neighbour) + frameWidth(east_neighbour)) < (frameX(c2) + frameWidth(c2)))
 
802
                            {
 
803
                                east_neighbour = c2;
 
804
                            }
 
805
                        }
 
806
                        else
 
807
                        {
 
808
                            east_neighbour = c2;
 
809
                        }
 
810
                    }
 
811
                    if ((frameX(c) + frameWidth(c)) < frameX(c2))
 
812
                    {
 
813
                        /* Check if c2 is closer to the client
 
814
                         * then the west neighbour already found
 
815
                         */
 
816
                        if (west_neighbour)
 
817
                        {
 
818
                            if (frameX(c2) < frameX(west_neighbour))
 
819
                            {
 
820
                                west_neighbour = c2;
 
821
                            }
 
822
                        }
 
823
                        else
 
824
                        {
 
825
                            west_neighbour = c2;
 
826
                        }
 
827
                    }
 
828
                }
 
829
            }
 
830
 
 
831
            /* Fill vertically */
 
832
            if (fill_type & CLIENT_FILL_VERT)
 
833
            {
 
834
                /* check if the neigbour client (c2) is located
 
835
                 * north or south of our client.
 
836
                 */
 
837
                if (segment_overlap (frameX(c), frameX(c) + frameWidth(c), frameX(c2), frameX(c2) + frameWidth(c2)))
 
838
                {
 
839
                    if ((frameY(c2) + frameHeight(c2)) < frameY(c))
 
840
                    {
 
841
                        if (north_neighbour)
 
842
                        {
 
843
                            /* Check if c2 is closer to the client
 
844
                             * then the north neighbour already found
 
845
                             */
 
846
                            if ((frameY(north_neighbour) + frameHeight(north_neighbour)) < (frameY(c2) + frameHeight(c2)))
 
847
                            {
 
848
                                north_neighbour = c2;
 
849
                            }
 
850
                        }
 
851
                        else
 
852
                        {
 
853
                            north_neighbour = c2;
 
854
                        }
 
855
                    }
 
856
                    if ((frameY(c) + frameHeight(c)) < frameY(c2))
 
857
                    {
 
858
                        if (south_neighbour)
 
859
                        {
 
860
                            /* Check if c2 is closer to the client
 
861
                             * then the south neighbour already found
 
862
                             */
 
863
                            if (frameY(c2) < frameY(south_neighbour))
 
864
                            {
 
865
                                south_neighbour = c2;
 
866
                            }
 
867
                        }
 
868
                        else
 
869
                        {
 
870
                            south_neighbour = c2;
 
871
                        }
 
872
                    }
 
873
                }
 
874
            }
 
875
        }
 
876
    }
 
877
 
 
878
    /* Compute the largest size available, based on struts, margins and Xinerama layout */
 
879
    tmp_x = frameX (c);
 
880
    tmp_y = frameY (c);
 
881
    tmp_h = frameHeight (c);
 
882
    tmp_w = frameWidth (c);
 
883
 
 
884
    cx = tmp_x + (tmp_w / 2);
 
885
    cy = tmp_y + (tmp_h / 2);
 
886
 
 
887
    myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
 
888
 
 
889
    full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x);
 
890
    full_y = MAX (screen_info->params->xfwm_margins[STRUTS_TOP], rect.y);
 
891
    full_w = MIN (screen_info->width - screen_info->params->xfwm_margins[STRUTS_RIGHT],
 
892
                  rect.x + rect.width) - full_x;
 
893
    full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM],
 
894
                  rect.y + rect.height) - full_y;
 
895
 
 
896
    if ((fill_type & CLIENT_FILL) == CLIENT_FILL)
 
897
    {
 
898
        mask = CWX | CWY | CWHeight | CWWidth;
 
899
        /* Adjust size to the largest size available, not covering struts */
 
900
        clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);
 
901
    }
 
902
    else if (fill_type & CLIENT_FILL_VERT)
 
903
    {
 
904
        mask = CWY | CWHeight;
 
905
        /* Adjust size to the tallest size available, for the current horizontal position/width */
 
906
        clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
 
907
    }
 
908
    else if (fill_type & CLIENT_FILL_HORIZ)
 
909
    {
 
910
        mask = CWX | CWWidth;
 
911
        /* Adjust size to the widest size available, for the current vertical position/height */
 
912
        clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
 
913
    }
 
914
 
 
915
    /* If there are neighbours, resize to their borders.
 
916
     * If not, resize to the largest size available that you just have computed.
 
917
     */
 
918
 
 
919
    wc.x = frameLeft(c);
 
920
    if (east_neighbour)
 
921
    {
 
922
        wc.x += MAX (frameX(east_neighbour) + frameWidth(east_neighbour), full_x);
 
923
    }
 
924
    else
 
925
    {
 
926
        wc.x += full_x;
 
927
    }
 
928
 
 
929
    wc.width = full_x - frameRight(c) - wc.x;
 
930
    if (west_neighbour)
 
931
    {
 
932
        wc.width += MIN (frameX(west_neighbour), full_w);
 
933
    }
 
934
    else
 
935
    {
 
936
        wc.width += full_w;
 
937
    }
 
938
 
 
939
    wc.y = frameTop(c);
 
940
    if (north_neighbour)
 
941
    {
 
942
        wc.y += MAX (frameY(north_neighbour) + frameHeight(north_neighbour), full_y);
 
943
    }
 
944
    else
 
945
    {
 
946
        wc.y += full_y;
 
947
    }
 
948
 
 
949
    wc.height = full_y - frameBottom(c) - wc.y;
 
950
    if (south_neighbour)
 
951
    {
 
952
        wc.height += MIN (frameY(south_neighbour), full_h);
 
953
    }
 
954
    else
 
955
    {
 
956
        wc.height += full_h;
 
957
    }
 
958
 
 
959
    TRACE ("Fill size request: (%d,%d) %dx%d", wc.x, wc.y, wc.width, wc.height);
 
960
    if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
 
961
    {
 
962
        clientConfigure(c, &wc, mask, NO_CFG_FLAG);
 
963
    }
 
964
}
 
965