39
39
ScaleAddonWindow::renderTitle ()
41
ADDON_SCREEN (screen);
43
int titleOpt = as->optionGetWindowTitle ();
46
titleOpt == ScaleaddonOptions::WindowTitleNoDisplay ||
47
!sWindow->hasSlot () ||
48
(titleOpt == ScaleaddonOptions::WindowTitleHighlightedWindowOnly &&
49
as->highlightedWindow != window->id ()))
41
53
CompText::Attrib attrib;
45
ADDON_SCREEN (screen);
52
if (!sWindow->hasSlot ())
55
titleOpt = as->optionGetWindowTitle ();
57
if (titleOpt == ScaleaddonOptions::WindowTitleNoDisplay)
60
if (titleOpt == ScaleaddonOptions::WindowTitleHighlightedWindowOnly &&
61
as->highlightedWindow != window->id ())
66
scale = sWindow->getSlot ().scale;
55
float scale = sWindow->getSlot ().scale;
67
56
attrib.maxWidth = window->width () * scale;
68
57
attrib.maxHeight = window->height () * scale;
94
84
ScaleAddonWindow::drawTitle (const GLMatrix &transform)
96
float x, y, width, height;
97
86
ScalePosition pos = sWindow->getCurrentPosition ();
98
87
CompRect geom = window->borderRect ();
100
width = text.getWidth ();
101
height = text.getHeight ();
89
float width = text.getWidth ();
90
float height = text.getHeight ();
103
x = pos.x () + window->x () + geom.width () * pos.scale / 2 - width / 2;
104
y = pos.y () + window->y () + geom.height () * pos.scale / 2 - height / 2;
92
float x = pos.x () + window->x () + geom.width () * pos.scale / 2 - width / 2;
93
float y = pos.y () + window->y () + geom.height () * pos.scale / 2 - height / 2;
106
95
text.draw (transform, floor (x), floor (y), 1.0f);
110
99
ScaleAddonWindow::drawHighlight (const GLMatrix &transform)
112
GLint oldBlendSrc, oldBlendDst;
113
GLushort colorData[4];
114
GLfloat vertexData[12];
104
GLint oldBlendSrc, oldBlendDst;
105
GLushort colorData[4];
106
GLfloat vertexData[12];
115
107
GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
116
float x, y, width, height;
117
ScalePosition pos = sWindow->getCurrentPosition ();
118
CompRect geom = window->borderRect ();
108
ScalePosition pos = sWindow->getCurrentPosition ();
109
CompRect geom = window->borderRect ();
120
111
ADDON_SCREEN (screen);
123
114
GLint oldBlendSrcAlpha, oldBlendDstAlpha;
129
x = pos.x () + window->x () - (window->border ().left * pos.scale);
130
y = pos.y () + window->y () - (window->border ().top * pos.scale);
131
width = geom.width () * pos.scale;
132
height = geom.height () * pos.scale;
117
float x = pos.x () + window->x () - (window->border ().left * pos.scale);
118
float y = pos.y () + window->y () - (window->border ().top * pos.scale);
119
float width = geom.width () * pos.scale;
120
float height = geom.height () * pos.scale;
134
122
/* we use a poor replacement for roundf()
135
123
* (available in C99 only) here */
222
210
CompAction::State state,
223
211
CompOption::Vector options)
227
213
if (!sScreen->hasGrab ())
230
w = screen->findWindow (highlightedWindow);
216
CompWindow *w = screen->findWindow (highlightedWindow);
232
219
w->close (screen->getCurrentTime ());
239
226
CompAction::State state,
240
227
CompOption::Vector options)
244
229
if (!sScreen->hasGrab ())
247
w = screen->findWindow (highlightedWindow);
232
CompWindow *w = screen->findWindow (highlightedWindow);
250
int x, y, xOffset, yOffset;
253
vp = w->defaultViewport ();
255
xOffset = (screen->vp ().x () - vp.x ()) * screen->width ();
256
yOffset = (screen->vp ().y () - vp.y ()) * screen->height ();
258
x = w->x () + xOffset;
259
y = w->y () + yOffset;
236
CompPoint vp = w->defaultViewport ();
238
int xOffset = (screen->vp ().x () - vp.x ()) * screen->width ();
239
int yOffset = (screen->vp ().y () - vp.y ()) * screen->height ();
241
int x = w->x () + xOffset;
242
int y = w->y () + yOffset;
261
244
if (optionGetConstrainPullToScreen ())
282
265
if (x != w->x () || y != w->y ())
284
ScalePosition pos, oldPos;
285
268
ADDON_WINDOW (w);
287
oldPos = aw->sWindow->getCurrentPosition ();
270
ScalePosition oldPos = aw->sWindow->getCurrentPosition ();
289
272
w->moveToViewportPosition (x, y, true);
291
274
/* Select this window when ending scale */
292
275
aw->sWindow->scaleSelectWindow ();
294
/* stop scaled window dissapearing */
277
/* stop scaled window disappearing */
295
278
pos.setX (oldPos.x () - xOffset);
296
279
pos.setY (oldPos.y () - yOffset);
304
287
o.push_back (CompOption ("root", CompOption::TypeInt));
305
288
o[0].value ().set ((int) screen->root ());
307
opt = CompOption::findOption (sScreen->getOptions (),
290
opt = CompOption::findOption (sScreen->getOptions (), "initiate_key", 0);
309
292
action = &opt->value ().action ();
311
294
if (action->terminate ())
337
320
CompAction::State state,
338
321
CompOption::Vector options)
342
323
if (!sScreen->hasGrab ())
345
w = screen->findWindow (highlightedWindow);
326
CompWindow *w = screen->findWindow (highlightedWindow);
351
330
ADDON_WINDOW (w);
353
332
if (!aw->sWindow->hasSlot ())
356
head = screen->outputDeviceForPoint (aw->sWindow->getSlot ().pos ());
357
output = screen->outputDevs ()[head];
335
int head = screen->outputDeviceForPoint (aw->sWindow->getSlot ().pos ());
336
CompRect output = screen->outputDevs ()[head];
359
338
/* damage old rect */
360
339
aw->cWindow->addDamage ();
372
350
aw->origSlot = slot;
373
351
aw->rescaled = true;
375
x1 = output.centerX () - geom.width () / 2 + w->border ().left;
376
y1 = output.centerY () - geom.height () / 2 + w->border ().top;
377
x2 = slot.x () + geom.width ();
378
y2 = slot.y () + geom.height ();
353
int x1 = output.centerX () - geom.width () / 2 + w->border ().left;
354
int y1 = output.centerY () - geom.height () / 2 + w->border ().top;
355
int x2 = slot.x () + geom.width ();
356
int y2 = slot.y () + geom.height ();
380
358
slot.scale = 1.0f;
381
359
slot.setGeometry (x1, y1, x2 - x1, y2 - y1);
450
430
if (state == ScaleScreen::Wait || state == ScaleScreen::Out)
452
if (as->optionGetWindowHighlight ())
454
if (window->id () == as->highlightedWindow)
455
drawHighlight (transform);
432
if (as->optionGetWindowHighlight () &&
433
window->id () == as->highlightedWindow)
434
drawHighlight (transform);
458
436
if (textAvailable)
459
437
drawTitle (transform);
508
486
if ((strcmp (pluginName, "scale") == 0) &&
509
487
(strcmp (eventName, "activate") == 0))
512
CompOption::getBoolOptionNamed (options, "active", false);
489
bool activated = CompOption::getBoolOptionNamed (options, "active", false);
583
x2 = x1 + WIN_W (ss->windows[win]) * as->scale;
584
y2 = y1 + WIN_H (ss->windows[win]) * as->scale;
559
int x2 = x1 + WIN_W (ss->windows[win]) * as->scale;
560
int y2 = y1 + WIN_H (ss->windows[win]) * as->scale;
586
for (int i = 0; i < ss->nWindows; i++)
562
for (int i = 0; i < ss->nWindows; ++i)
616
592
double bestOverlap = 1e31, overlap;
621
y1 = ss->slots[win].y1;
622
y2 = ss->slots[win].y1 + WIN_H (ss->windows[win]) * as->scale;
597
int y1 = ss->slots[win].y1;
598
int y2 = ss->slots[win].y1 + WIN_H (ss->windows[win]) * as->scale;
624
w = WIN_W (ss->windows[win]) * as->scale;
600
int w = WIN_W (ss->windows[win]) * as->scale;
625
601
*bestX = ss->slots[win].x1;
627
for (i = 0; i < ss->nWindows; i++)
603
for (int i = 0; i < ss->nWindows; ++i)
629
605
CompWindow *lw = ss->windows[i];
636
613
if (ss->slots[i].x1 - w >= 0)
640
overlap = layoutOrganicCalculateOverlap (s, win,
615
double overlap = layoutOrganicCalculateOverlap (s, win,
644
619
if (overlap < bestOverlap)
647
622
bestOverlap = overlap;
650
626
if (WIN_W (lw) * as->scale + ss->slots[i].x1 + w < areaWidth)
654
overlap = layoutOrganicCalculateOverlap (s, win,
656
WIN_W (lw) * as->scale,
628
double overlap = layoutOrganicCalculateOverlap (s, win,
630
WIN_W (lw) * as->scale,
659
633
if (overlap < bestOverlap)
692
667
double bestOverlap = 1e31, overlap;
697
x1 = ss->slots[win].x1;
698
x2 = ss->slots[win].x1 + WIN_W (ss->windows[win]) * as->scale;
699
h = WIN_H (ss->windows[win]) * as->scale;
672
int x1 = ss->slots[win].x1;
673
int x2 = ss->slots[win].x1 + WIN_W (ss->windows[win]) * as->scale;
674
int h = WIN_H (ss->windows[win]) * as->scale;
700
675
*bestY = ss->slots[win].y1;
702
for (i = 0; i < ss->nWindows; i++)
677
for (int i = 0; i < ss->nWindows; ++i)
704
679
CompWindow *w = ss->windows[i];
712
687
if (ss->slots[i].y1 - h >= 0 && ss->slots[i].y1 < areaHeight)
715
overlap = layoutOrganicCalculateOverlap (s, win, x1,
716
ss->slots[i].y1 - h);
689
double overlap = layoutOrganicCalculateOverlap (s, win, x1,
690
ss->slots[i].y1 - h);
717
691
if (overlap < bestOverlap)
719
693
*bestY = ss->slots[i].y1 - h;
720
694
bestOverlap = overlap;
723
698
if (WIN_H (w) * as->scale + ss->slots[i].y1 > 0 &&
724
699
WIN_H (w) * as->scale + h + ss->slots[i].y1 < areaHeight)
728
overlap = layoutOrganicCalculateOverlap (s, win, x1,
729
WIN_H (w) * as->scale +
701
double overlap = layoutOrganicCalculateOverlap (s, win, x1,
702
WIN_H (w) * as->scale +
732
705
if (overlap < bestOverlap)
831
spacing = ss->opt[SCALE_SCREEN_OPTION_SPACING].value.i;
807
int spacing = ss->opt[SCALE_SCREEN_OPTION_SPACING].value.i;
833
809
while (layoutOrganicLocalSearch (s, areaWidth, areaHeight))
835
for (i = 0; i < ss->nWindows; i++)
811
for (int i = 0; i < ss->nWindows; ++i)
837
int centerX, centerY;
838
int newX, newY, newWidth, newHeight;
840
813
w = ss->windows[i];
842
centerX = ss->slots[i].x1 + WIN_W (w) / 2;
843
centerY = ss->slots[i].y1 + WIN_H (w) / 2;
815
int centerX = ss->slots[i].x1 + WIN_W (w) / 2;
816
int centerY = ss->slots[i].y1 + WIN_H (w) / 2;
845
newWidth = (int)((1.0 - ORGANIC_STEP) *
818
int newWidth = (int)((1.0 - ORGANIC_STEP) *
846
819
(double)WIN_W (w)) - spacing / 2;
847
newHeight = (int)((1.0 - ORGANIC_STEP) *
820
int newHeight = (int)((1.0 - ORGANIC_STEP) *
848
821
(double)WIN_H (w)) - spacing / 2;
849
newX = centerX - (newWidth / 2);
850
newY = centerY - (newHeight / 2);
822
int newX = centerX - (newWidth / 2);
823
int newY = centerY - (newHeight / 2);
852
825
ss->slots[i].x1 = newX;
853
826
ss->slots[i].y1 = newY;
862
835
layoutOrganicThumbs (CompScreen *s)
866
839
XRectangle workArea;
871
moMode = ss->opt[SCALE_SCREEN_OPTION_MULTIOUTPUT_MODE].value.i;
844
int moMode = ss->opt[SCALE_SCREEN_OPTION_MULTIOUTPUT_MODE].value.i;
874
848
case SCALE_MOMODE_ALL:
875
849
workArea = s->workArea;
877
852
case SCALE_MOMODE_CURRENT:
879
854
workArea = s->outputDev[s->currentOutputDev].workArea;
885
860
qsort (ss->windows, ss->nWindows, sizeof(CompWindow *),
886
861
organicCompareWindows);
888
for (i = 0; i < ss->nWindows; i++)
863
for (i = 0; i < ss->nWindows; ++i)
890
865
w = ss->windows[i];
891
866
SCALE_WINDOW (w);
925
900
layoutOrganicRemoveOverlap (s, workArea.width - workArea.x,
926
901
workArea.height - workArea.y);
927
for (i = 0; i < ss->nWindows; i++)
902
for (i = 0; i < ss->nWindows; ++i)
929
904
w = ss->windows[i];
930
905
SCALE_WINDOW (w);
960
935
if (border.intersects (targets[w]))
962
938
// Is there a better way to do this?
963
939
std::map <ScaleWindow *, CompRegion>::const_iterator i;
964
941
for (i = targets.begin (); i != targets.end (); ++i)
966
943
if (w == (*i).first)
968
946
if (targets[w].intersects ((*i).second))
975
953
ScaleAddonScreen::layoutNaturalThumbs ()
977
ScaleScreen::WindowList windows = ScaleScreen::get (screen)->getWindows ();
979
CompRect area = screen->workArea ();
980
CompRect bounds = area;
955
ScaleScreen::WindowList windows = ScaleScreen::get (screen)->getWindows ();
957
CompRect area = screen->workArea ();
958
CompRect bounds = area;
981
959
std::map <ScaleWindow *, CompRegion> targets;
982
std::map <ScaleWindow *, int> directions;
960
std::map <ScaleWindow *, int> directions;
986
964
if (windows.size () == 1)
1058
1039
ySection = (directions[w] % 2 ? 2 : 0);
1061
if (xSection == 0 && ySection == 0)
1042
if (xSection == 0 && ySection == 0)
1063
1044
moveX = bounds.left () - targets[w].boundingRect ().centerX ();
1064
1045
moveY = bounds.top () - targets[w].boundingRect ().centerY ();
1066
if (xSection == 2 && ySection == 0)
1047
if (xSection == 2 && ySection == 0)
1068
1049
moveX = bounds.right () - targets[w].boundingRect ().centerX ();
1069
1050
moveY = bounds.top () - targets[w].boundingRect ().centerY ();
1071
if (xSection == 2 && ySection == 2)
1052
if (xSection == 2 && ySection == 2)
1073
1054
moveX = bounds.right () - targets[w].boundingRect ().centerX ();
1074
1055
moveY = bounds.bottom () - targets[w].boundingRect ().centerY ();
1076
if (xSection == 0 && ySection == 2)
1057
if (xSection == 0 && ySection == 2)
1078
1059
moveX = bounds.left () - targets[w].boundingRect ().centerX ();
1079
1060
moveY = bounds.right () - targets[w].boundingRect ().centerY ();
1081
if (moveX != 0 || moveY != 0)
1082
targets[w].translate (moveX, moveY);
1062
if (moveX != 0 || moveY != 0)
1063
targets[w].translate (moveX, moveY);
1094
1075
// Work out scaling by getting the most top-left and most bottom-right window coords.
1095
1076
// The 20's and 10's are so that the windows don't touch the edge of the screen.
1097
1079
if (bounds == area)
1098
scale = 1.0; // Don't add borders to the screen
1080
scale = 1.0; // Don't add borders to the screen
1099
1081
else if (area.width () / double (bounds.width ()) < area.height () / double (bounds.height ()))
1100
scale = (area.width () - 20) / double (bounds.width ());
1082
scale = (area.width () - 20) / double (bounds.width ());
1102
scale = (area.height () - 20) / double (bounds.height ());
1084
scale = (area.height () - 20) / double (bounds.height ());
1103
1086
// Make bounding rect fill the screen size for later steps
1104
1087
bounds = CompRect (
1105
bounds.x () - (area.width () - 20 - bounds.width () * scale ) / 2 - 10 / scale,
1106
bounds.y () - (area.height () - 20 - bounds.height () * scale ) / 2 - 10 / scale,
1107
area.width () / scale,
1108
area.height () / scale
1088
bounds.x () - (area.width () - 20 - bounds.width () * scale ) / 2 - 10 / scale,
1089
bounds.y () - (area.height () - 20 - bounds.height () * scale ) / 2 - 10 / scale,
1090
area.width () / scale,
1091
area.height () / scale
1111
1094
// Move all windows back onto the screen and set their scale
1112
1095
foreach (ScaleWindow *w, windows)
1114
targets[w] = CompRect (
1115
(targets[w].boundingRect ().x () - bounds.x () ) * scale + area.x (),
1116
(targets[w].boundingRect ().y () - bounds.y ()) * scale + area.y (),
1117
targets[w].boundingRect ().width () * scale,
1118
targets[w].boundingRect ().height () * scale
1097
targets[w] = CompRect (
1098
(targets[w].boundingRect ().x () - bounds.x () ) * scale + area.x (),
1099
(targets[w].boundingRect ().y () - bounds.y ()) * scale + area.y (),
1100
targets[w].boundingRect ().width () * scale,
1101
targets[w].boundingRect ().height () * scale
1120
1104
ScaleSlot slt (targets[w].boundingRect ());
1121
1105
slt.scale = scale;
1122
1106
slt.filled = true;
1135
1119
borderRegion ^= areaRegion;
1137
1121
bool moved = false;
1141
1127
foreach (ScaleWindow *w, windows)
1143
1129
CompRegion oldRegion;
1145
1131
// This may cause some slight distortion if the windows are enlarged a large amount
1146
1132
int widthDiff = optionGetNaturalPrecision ();
1147
1133
int heightDiff = ((w->window->height () / w->window->width ()) *
1148
1134
(targets[w].boundingRect ().width() + widthDiff)) - targets[w].boundingRect ().height ();
1149
1135
int xDiff = widthDiff / 2; // Also move a bit in the direction of the enlarge, allows the
1150
1136
int yDiff = heightDiff / 2; // center windows to be enlarged if there is gaps on the side.
1152
1138
// Attempt enlarging to the top-right
1153
1139
oldRegion = targets[w];
1154
1140
targets[w] = CompRegion (
1157
1143
targets[w].boundingRect ().width () + widthDiff,
1158
1144
targets[w].boundingRect ().height () + heightDiff
1160
1147
if (isOverlappingAny (w, targets, borderRegion))
1161
1148
targets[w] = oldRegion;
1165
1152
// Attempt enlarging to the bottom-right
1166
1153
oldRegion = targets[w];
1167
1154
targets[w] = CompRegion(
1183
1170
targets[w].boundingRect ().width() + widthDiff,
1184
1171
targets[w].boundingRect ().height() + heightDiff
1186
1174
if (isOverlappingAny (w, targets, borderRegion))
1187
1175
targets[w] = oldRegion;
1191
1179
// Attempt enlarging to the top-left
1192
1180
oldRegion = targets[w];
1193
1181
targets[w] = CompRegion (
1196
1184
targets[w].boundingRect ().width() + widthDiff,
1197
1185
targets[w].boundingRect ().height() + heightDiff
1199
1188
if (isOverlappingAny (w, targets, borderRegion))
1200
1189
targets[w] = oldRegion;
1207
1196
while (moved && iterCount < 100);
1325
1315
ScaleAddonPluginVTable::init ()
1327
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1328
!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1329
!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) ||
1330
!CompPlugin::checkPluginABI ("scale", COMPIZ_SCALE_ABI))
1333
if (!CompPlugin::checkPluginABI ("text", COMPIZ_TEXT_ABI))
1317
if (CompPlugin::checkPluginABI ("text", COMPIZ_TEXT_ABI))
1318
textAvailable = true;
1335
1321
compLogMessage ("scaleaddon", CompLogLevelInfo,
1336
1322
"Text Plugin not loaded, no text will be drawn.");
1337
1323
textAvailable = false;
1340
textAvailable = true;
1326
if (CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) &&
1327
CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) &&
1328
CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) &&
1329
CompPlugin::checkPluginABI ("scale", COMPIZ_SCALE_ABI))