422
421
int left, right, top, bottom;
423
422
int x1, y1, x2, y2;
426
result = XGetWindowProperty (screen->dpy (), id,
427
decorAtom, 0L, 1024L, false,
428
XA_INTEGER, &actual, &format,
431
if (result != Success || !n || !data)
434
prop = (long *) data;
436
if (decor_property_get_version (prop) != decor_version ())
438
compLogMessage ("decoration", CompLogLevelWarn,
439
"Property ignored because "
440
"version is %d and decoration plugin version is %d\n",
441
decor_property_get_version (prop), decor_version ());
447
type = decor_property_get_type (prop);
449
424
if (type == WINDOW_DECORATION_TYPE_PIXMAP &&
450
425
!DecorScreen::get (screen)->cmActive)
427
compLogMessage ("decor", CompLogLevelWarn, "requested a pixmap type decoration when compositing isn't available");
453
431
if (type == WINDOW_DECORATION_TYPE_PIXMAP)
455
nQuad = (n - BASE_PROP_SIZE) / QUAD_PROP_SIZE;
457
435
quad = new decor_quad_t [nQuad];
438
compLogMessage ("decor", CompLogLevelWarn, "failed to allocate %i quads\n", nQuad);
464
nQuad = decor_pixmap_property_to_quads (prop, n, &pixmap, &input,
442
nQuad = decor_pixmap_property_to_quads (prop, nOffset, size, &pixmap, &input,
465
443
&border, &maxInput,
466
&maxBorder, &minWidth, &minHeight, quad);
444
&maxBorder, &minWidth, &minHeight,
445
&frameType, &frameState, &frameActions, quad);
599
584
delete decoration;
587
DecorationList::DecorationList () :
593
DecorationList::updateDecoration (Window id,
596
unsigned long n, nleft;
603
/* FIXME: Should really check the property to see
604
* if the decoration changed, and /then/ release
605
* and re-update it, but for now just releasing all */
608
result = XGetWindowProperty (screen->dpy (), id,
610
PROP_HEADER_SIZE + 6 * (BASE_PROP_SIZE +
611
QUAD_PROP_SIZE * N_QUADS_MAX),
612
false, XA_INTEGER, &actual, &format,
615
if (result != Success || !n || !data)
618
/* Attempted to read the reasonable amount of
619
* around 6 pixmap decorations, if there are more, we need
620
* an additional roundtrip to read everything else
626
result = XGetWindowProperty (screen->dpy (), id, decorAtom, 0L,
627
n + nleft, false, XA_INTEGER, &actual, &format,
630
if (result != Success || !n || !data)
634
prop = (long *) data;
636
if (decor_property_get_version (prop) != decor_version ())
638
compLogMessage ("decoration", CompLogLevelWarn,
639
"Property ignored because "
640
"version is %d and decoration plugin version is %d\n",
641
decor_property_get_version (prop), decor_version ());
647
type = decor_property_get_type (prop);
649
for (int i = 0; i < decor_property_get_num (prop); i++)
651
Decoration *d = Decoration::create (id, prop, n, type, i);
603
670
DecorWindow::updateDecoration ()
605
Decoration *decoration;
607
672
bindFailed = false;
608
decoration = Decoration::create (window->id (), dScreen->winDecorAtom);
611
Decoration::release (decor);
674
decor.updateDecoration (window->id (), dScreen->winDecorAtom);
614
676
pixmapFailed = true;
616
678
pixmapFailed = false;
621
681
WindowDecoration *
867
DecorWindow::matchType (CompWindow *w,
868
unsigned int decorType)
870
const unsigned int nTypeStates = 5;
873
unsigned int compFlag;
874
unsigned int decorFlag;
877
{ CompWindowTypeNormalMask, DECOR_WINDOW_TYPE_NORMAL },
878
{ CompWindowTypeDialogMask, DECOR_WINDOW_TYPE_DIALOG },
879
{ CompWindowTypeModalDialogMask, DECOR_WINDOW_TYPE_MODAL_DIALOG },
880
{ CompWindowTypeMenuMask, DECOR_WINDOW_TYPE_MENU },
881
{ CompWindowTypeUtilMask, DECOR_WINDOW_TYPE_UTILITY}
884
for (i = 0; i < nTypeStates; i++)
886
if ((decorType & typeStates[i].decorFlag) && (w->type () & typeStates[i].compFlag))
894
DecorWindow::matchState (CompWindow *w,
895
unsigned int decorState)
897
const unsigned int nStateStates = 3;
900
unsigned int compFlag;
901
unsigned int decorFlag;
904
{ CompWindowStateMaximizedVertMask, DECOR_WINDOW_STATE_MAXIMIZED_VERT },
905
{ CompWindowStateMaximizedHorzMask, DECOR_WINDOW_STATE_MAXIMIZED_HORZ },
906
{ CompWindowStateShadedMask, DECOR_WINDOW_STATE_SHADED }
909
/* Active is a separate check */
911
if (screen->activeWindow () == w->id ())
912
decorState &= ~(DECOR_WINDOW_STATE_FOCUS);
914
for (i = 0; i < nStateStates; i++)
916
if ((decorState & stateStates[i].decorFlag) && (w->state () & stateStates[i].compFlag))
917
decorState &= ~(stateStates[i].decorFlag);
920
return (decorState == 0);
924
DecorWindow::matchActions (CompWindow *w,
925
unsigned int decorActions)
927
const unsigned int nActionStates =16;
930
unsigned int compFlag;
931
unsigned int decorFlag;
934
{ DECOR_WINDOW_ACTION_RESIZE_HORZ, CompWindowActionResizeMask },
935
{ DECOR_WINDOW_ACTION_RESIZE_VERT, CompWindowActionResizeMask },
936
{ DECOR_WINDOW_ACTION_CLOSE, CompWindowActionCloseMask },
937
{ DECOR_WINDOW_ACTION_MINIMIZE, CompWindowActionMinimizeMask },
938
{ DECOR_WINDOW_ACTION_UNMINIMIZE,CompWindowActionMinimizeMask },
939
{ DECOR_WINDOW_ACTION_MAXIMIZE_HORZ, CompWindowActionMaximizeHorzMask },
940
{ DECOR_WINDOW_ACTION_MAXIMIZE_VERT, CompWindowActionMaximizeVertMask },
941
{ DECOR_WINDOW_ACTION_UNMAXIMIZE_HORZ, CompWindowActionMaximizeHorzMask },
942
{ DECOR_WINDOW_ACTION_UNMAXIMIZE_VERT, CompWindowActionMaximizeVertMask },
943
{ DECOR_WINDOW_ACTION_SHADE, CompWindowActionShadeMask },
944
{ DECOR_WINDOW_ACTION_UNSHADE, CompWindowActionShadeMask },
945
{ DECOR_WINDOW_ACTION_STICK, CompWindowActionStickMask },
946
{ DECOR_WINDOW_ACTION_UNSTICK, CompWindowActionStickMask },
947
{ DECOR_WINDOW_ACTION_FULLSCREEN, CompWindowActionFullscreenMask },
948
{ DECOR_WINDOW_ACTION_ABOVE, CompWindowActionAboveMask },
949
{ DECOR_WINDOW_ACTION_BELOW, CompWindowActionBelowMask },
952
/* Active is a separate check */
953
for (i = 0; i < nActionStates; i++)
955
if ((decorActions & actionStates[i].decorFlag) && (w->type () & actionStates[i].compFlag))
956
decorActions &= ~(actionStates[i].decorFlag);
959
return (decorActions == 0);
963
DecorationList::findMatchingDecoration (CompWindow *w,
966
Decoration *decoration = NULL;
971
const unsigned int typeMatch = (1 << 0);
972
const unsigned int stateMatch = (1 << 1);
973
const unsigned int actionsMatch = (1 << 2);
975
unsigned int currentDecorState = 0;
977
decoration = (sizeCheck ? dw->checkSize (mList.front ()) : true) ? mList.front () : NULL;
979
foreach (Decoration *d, mList)
981
if (DecorWindow::matchType (w, d->frameType))
983
if (!(typeMatch & currentDecorState) && (!sizeCheck || dw->checkSize (d)))
986
currentDecorState |= typeMatch;
989
if (DecorWindow::matchState (w, d->frameState) && (!sizeCheck || dw->checkSize (d)))
991
if (!(stateMatch & currentDecorState))
994
currentDecorState |= stateMatch;
997
if (DecorWindow::matchActions (w, d->frameActions) && (!sizeCheck || dw->checkSize (d)))
999
if (!(actionsMatch & currentDecorState))
1002
currentDecorState |= actionsMatch;
1004
/* Perfect match, no need to continue searching */
807
1017
DecorWindow::update (bool allowDecoration)
809
1019
Decoration *old, *decoration = NULL;
858
if (decor && checkSize (decor))
1068
/* Attempt to find a matching */
1069
decoration = decor.findMatchingDecoration (window, true);
1073
/* Find an appropriate default decoration to use */
863
1074
if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_PIXMAP &&
864
1075
dScreen->cmActive &&
865
1076
!(dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW &&
868
if (window->id () == screen->activeWindow ())
869
decoration = dScreen->decor[DECOR_ACTIVE];
871
decoration = dScreen->decor[DECOR_NORMAL];
1079
decoration = dScreen->decor[DECOR_ACTIVE].findMatchingDecoration (window, false);
1082
compLogMessage ("decor", CompLogLevelWarn, "No default decoration found, placement will not be correct");
873
1084
else if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW)
874
1085
decoration = &dScreen->windowDefault;
1571
/* Different decorator became active, update all decorations */
1362
1572
if (dmWin != this->dmWin)
1366
1576
this->dmSupports = dmSupports;
1578
/* Create new default decorations */
1370
1581
for (i = 0; i < DECOR_NUM; i++)
1371
decor[i] = Decoration::create (screen->root (), decorAtom[i]);
1583
decor[i].updateDecoration (screen->root (), decorAtom[i]);
1588
/* No decorator active, destroy all decorations */
1375
1589
for (i = 0; i < DECOR_NUM; i++)
1379
Decoration::release (decor[i]);
1384
foreach (CompWindow *w, screen->windows ())
1386
DecorWindow *dw = DecorWindow::get (w);
1390
Decoration::release (dw->decor);
1593
foreach (CompWindow *w, screen->windows ())
1594
DecorWindow::get (w)->decor.mList.clear ();