Merge lp:~compiz-team/compiz/0.9.11.2 into lp:compiz/0.9.11

Proposed by Christopher Townsend
Status: Merged
Approved by: Stephen M. Webb
Approved revision: 3865
Merged at revision: 3864
Proposed branch: lp:~compiz-team/compiz/0.9.11.2
Merge into: lp:compiz/0.9.11
Diff against target: 754 lines (+289/-106)
11 files modified
debian/changelog (+14/-0)
debian/compiz-core.install (+0/-1)
debian/compiz-plugins-default.install (+1/-0)
debian/compiz-plugins.install (+1/-0)
debian/compiz-plugins.install.armel (+1/-0)
debian/compiz-plugins.install.armhf (+1/-0)
debian/control (+2/-0)
plugins/scale/include/scale/scale.h (+0/-1)
plugins/scale/scale.xml.in (+14/-0)
plugins/scale/src/privates.h (+10/-4)
plugins/scale/src/scale.cpp (+245/-100)
To merge this branch: bzr merge lp:~compiz-team/compiz/0.9.11.2
Reviewer Review Type Date Requested Status
Stephen M. Webb Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+226510@code.launchpad.net

Commit message

Prepare for upstream micro-release 0.9.11.2 which includes fixes for the following bugs:
Bug #607796: Launcher, Window management - Dragging and holding a selection over an entry in the Launcher should spread out windows belonging to that application
Bug #727904: Launcher, Window management - Switching between spreads when dragging a file over the Launcher is broken
Bug #1308112: Scale should not select a window when clicking on an empty area

Description of the change

Prepare for upstream micro-release 0.9.11.2.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Stephen M. Webb (bregma) wrote :

OK, lets get this in to 14.04

review: Approve
lp:~compiz-team/compiz/0.9.11.2 updated
3866. By Christopher Townsend

Previously merged in wrong value for breaks/replaces and this fixes it.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-07-01 11:51:27 +0000
3+++ debian/changelog 2014-07-14 13:30:01 +0000
4@@ -1,3 +1,17 @@
5+compiz (1:0.9.11.1+14.04.20140701-0ubuntu2) trusty; urgency=medium
6+
7+ [ Marco Trevisan (TreviƱo) ]
8+ * Scale: use XShape extension to exclude dnd input in the screen-parts
9+ outside workArea This will work property also in multi-monitor,
10+ without requiring multiple X windows for each output device. Also
11+ don't terminate the scale unless a drag-n-drop action is not really
12+ over. Add a spinner that shows up over a window, during the DnD
13+ timeout. Plus, make sure we terminate the scale without focusing the
14+ selected icon when cancelling it and some code cleanup (LP: #607796)
15+ (LP: #727904) (LP: #1308112)
16+
17+ -- Chris Townsend <christopher.townsend@canonical.com> Fri, 11 Jul 2014 12:26:28 -0400
18+
19 compiz (1:0.9.11.1+14.04.20140701-0ubuntu1) trusty; urgency=medium
20
21 [ Chris Townsend ]
22
23=== modified file 'debian/compiz-core.install'
24--- debian/compiz-core.install 2012-06-19 11:22:48 +0000
25+++ debian/compiz-core.install 2014-07-14 13:30:01 +0000
26@@ -1,6 +1,5 @@
27 debian/tmp/usr/bin/compiz*
28 debian/tmp/usr/lib/libcompiz_core.so.*
29-debian/tmp/usr/share/compiz/cube/images/*.png
30 debian/tmp/usr/share/compiz/*.png
31 debian/tmp/usr/share/compiz/core.xml
32 debian/source_compiz.py usr/share/apport/package-hooks
33
34=== modified file 'debian/compiz-plugins-default.install'
35--- debian/compiz-plugins-default.install 2013-08-19 15:39:46 +0000
36+++ debian/compiz-plugins-default.install 2014-07-14 13:30:01 +0000
37@@ -17,6 +17,7 @@
38 debian/tmp/usr/*/compiz/*regex.*
39 debian/tmp/usr/*/compiz/*resize.*
40 debian/tmp/usr/*/compiz/*scale.*
41+debian/tmp/usr/share/compiz/scale
42 debian/tmp/usr/*/compiz/*session.*
43 debian/tmp/usr/*/compiz/*snap.*
44 debian/tmp/usr/*/compiz/*vpswitch.*
45
46=== modified file 'debian/compiz-plugins.install'
47--- debian/compiz-plugins.install 2013-08-19 15:39:46 +0000
48+++ debian/compiz-plugins.install 2014-07-14 13:30:01 +0000
49@@ -4,6 +4,7 @@
50 debian/tmp/usr/*/compiz/*clone.*
51 debian/tmp/usr/*/compiz/*crashhandler.*
52 debian/tmp/usr/*/compiz/*cube.*
53+debian/tmp/usr/share/compiz/cube
54 debian/tmp/usr/*/compiz/*cubeaddon.*
55 debian/tmp/usr/share/compiz/cubeaddon
56 debian/tmp/usr/*/compiz/*dbus.*
57
58=== modified file 'debian/compiz-plugins.install.armel'
59--- debian/compiz-plugins.install.armel 2013-07-28 10:35:40 +0000
60+++ debian/compiz-plugins.install.armel 2014-07-14 13:30:01 +0000
61@@ -5,6 +5,7 @@
62 debian/tmp/usr/*/compiz/*copytex.*
63 debian/tmp/usr/*/compiz/*crashhandler.*
64 debian/tmp/usr/*/compiz/*cube.*
65+debian/tmp/usr/share/compiz/cube
66 debian/tmp/usr/*/compiz/*cubeaddon.*
67 debian/tmp/usr/share/compiz/cubeaddon
68 debian/tmp/usr/*/compiz/*dbus.*
69
70=== modified file 'debian/compiz-plugins.install.armhf'
71--- debian/compiz-plugins.install.armhf 2013-07-28 10:35:40 +0000
72+++ debian/compiz-plugins.install.armhf 2014-07-14 13:30:01 +0000
73@@ -5,6 +5,7 @@
74 debian/tmp/usr/*/compiz/*copytex.*
75 debian/tmp/usr/*/compiz/*crashhandler.*
76 debian/tmp/usr/*/compiz/*cube.*
77+debian/tmp/usr/share/compiz/cube
78 debian/tmp/usr/*/compiz/*cubeaddon.*
79 debian/tmp/usr/share/compiz/cubeaddon
80 debian/tmp/usr/*/compiz/*dbus.*
81
82=== modified file 'debian/control'
83--- debian/control 2014-02-16 21:23:37 +0000
84+++ debian/control 2014-07-14 13:30:01 +0000
85@@ -188,8 +188,10 @@
86 Replaces: compiz-plugins-main (<< 1:0.9.8),
87 compiz-plugins-extra (<< 1:0.9.8),
88 compiz-plugins-main-default (<< 1:0.9.8),
89+ compiz-core (<= 1:0.9.11.1+14.04.20140701-0ubuntu1),
90 Breaks: compiz-plugins-main (<< 1:0.9.8),
91 compiz-plugins-extra (<< 1:0.9.8),
92+ compiz-core (<= 1:0.9.11.1+14.04.20140701-0ubuntu1),
93 Description: OpenGL window and compositing manager - plugins
94 Compiz brings to life a variety of visual effects that make the Linux desktop
95 easier to use, more powerful and intuitive, and more accessible for users
96
97=== added directory 'plugins/scale/images'
98=== added file 'plugins/scale/images/dnd-spinner-000.png'
99Binary files plugins/scale/images/dnd-spinner-000.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-000.png 2014-07-14 13:30:01 +0000 differ
100=== added file 'plugins/scale/images/dnd-spinner-125.png'
101Binary files plugins/scale/images/dnd-spinner-125.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-125.png 2014-07-14 13:30:01 +0000 differ
102=== added file 'plugins/scale/images/dnd-spinner-250.png'
103Binary files plugins/scale/images/dnd-spinner-250.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-250.png 2014-07-14 13:30:01 +0000 differ
104=== added file 'plugins/scale/images/dnd-spinner-375.png'
105Binary files plugins/scale/images/dnd-spinner-375.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-375.png 2014-07-14 13:30:01 +0000 differ
106=== added file 'plugins/scale/images/dnd-spinner-500.png'
107Binary files plugins/scale/images/dnd-spinner-500.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-500.png 2014-07-14 13:30:01 +0000 differ
108=== added file 'plugins/scale/images/dnd-spinner-625.png'
109Binary files plugins/scale/images/dnd-spinner-625.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-625.png 2014-07-14 13:30:01 +0000 differ
110=== added file 'plugins/scale/images/dnd-spinner-750.png'
111Binary files plugins/scale/images/dnd-spinner-750.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-750.png 2014-07-14 13:30:01 +0000 differ
112=== added file 'plugins/scale/images/dnd-spinner-875.png'
113Binary files plugins/scale/images/dnd-spinner-875.png 1970-01-01 00:00:00 +0000 and plugins/scale/images/dnd-spinner-875.png 2014-07-14 13:30:01 +0000 differ
114=== modified file 'plugins/scale/include/scale/scale.h'
115--- plugins/scale/include/scale/scale.h 2012-10-12 09:05:18 +0000
116+++ plugins/scale/include/scale/scale.h 2014-07-14 13:30:01 +0000
117@@ -100,7 +100,6 @@
118
119 const CompMatch & getCustomMatch () const;
120 const WindowList& getWindows () const;
121-
122
123 void relayoutSlots (const CompMatch& match);
124
125
126=== modified file 'plugins/scale/scale.xml.in'
127--- plugins/scale/scale.xml.in 2014-02-17 20:36:26 +0000
128+++ plugins/scale/scale.xml.in 2014-07-14 13:30:01 +0000
129@@ -7,10 +7,12 @@
130 <deps>
131 <requirement>
132 <plugin>opengl</plugin>
133+ <plugin>imgpng</plugin>
134 </requirement>
135 <relation type="after">
136 <plugin>fade</plugin>
137 <plugin>decor</plugin>
138+ <plugin>imgpng</plugin>
139 </relation>
140 </deps>
141 <options>
142@@ -104,6 +106,18 @@
143 <min>0</min>
144 <max>250</max>
145 </option>
146+ <option name="dnd_timeout_spinner" type="bool">
147+ <_short>Show a spinner during th Drag and Drop timeout</_short>
148+ <_long>Whether to show a spinner over the windows during dnd Timeout.</_long>
149+ <default>true</default>
150+ </option>
151+ <option name="dnd_timeout_spinner_speed" type="int">
152+ <_short>The speed of the DnD timeout spinner</_short>
153+ <_long>The animation speed (in ms) of the Drag and Drop spinner.</_long>
154+ <default>100</default>
155+ <min>50</min>
156+ <max>250</max>
157+ </option>
158 <option name="multioutput_mode" type="int">
159 <_short>Multi Output Mode</_short>
160 <_long>Selects where windows are scaled if multiple output devices are used.</_long>
161
162=== modified file 'plugins/scale/src/privates.h'
163--- plugins/scale/src/privates.h 2014-02-17 03:02:06 +0000
164+++ plugins/scale/src/privates.h 2014-07-14 13:30:01 +0000
165@@ -45,7 +45,6 @@
166 {
167 public:
168 PrivateScaleScreen (CompScreen *);
169- ~PrivateScaleScreen ();
170
171 void handleEvent (XEvent *event);
172
173@@ -57,6 +56,7 @@
174 CompOutput *, unsigned int);
175
176 void activateEvent (bool activating);
177+ void terminateScale (bool accept);
178
179 void layoutSlotsForArea (const CompRect&, int);
180 void layoutSlots ();
181@@ -70,7 +70,8 @@
182
183 ScaleWindow * checkForWindowAt (int x, int y);
184
185- void sendDndStatusMessage (Window);
186+ void sendDndStatusMessage (Window, bool asks);
187+ void sendDndFinishedMessage (Window);
188
189 bool
190 actionShouldToggle (CompAction *action,
191@@ -98,6 +99,7 @@
192 void windowRemove (CompWindow *);
193
194 bool hoverTimeout ();
195+ bool dndCheckTimeout ();
196
197 void updateOpacity ();
198
199@@ -121,14 +123,18 @@
200 CompScreen::GrabHandle grabIndex;
201
202 Window dndTarget;
203+ Atom xdndSelection;
204+ Atom xdndFinished;
205+ Atom xdndActionAsk;
206+
207+ std::vector<GLTexture::List> dndSpinners;
208
209 CompTimer hover;
210+ CompTimer dndCheck;
211
212 ScaleScreen::State state;
213 int moreAdjust;
214
215- Cursor cursor;
216-
217 std::vector<ScaleSlot> slots;
218 int nSlots;
219
220
221=== modified file 'plugins/scale/src/scale.cpp'
222--- plugins/scale/src/scale.cpp 2014-04-04 14:44:54 +0000
223+++ plugins/scale/src/scale.cpp 2014-07-14 13:30:01 +0000
224@@ -30,7 +30,7 @@
225 #include <sys/time.h>
226
227 #include <X11/Xatom.h>
228-#include <X11/cursorfont.h>
229+#include <X11/extensions/shape.h>
230
231 #include <core/atoms.h>
232 #include <scale/scale.h>
233@@ -244,6 +244,70 @@
234 }
235 }
236 }
237+
238+ if (spScreen->optionGetDndTimeoutSpinner () &&
239+ priv->window->id() == spScreen->selectedWindow &&
240+ priv->slot &&
241+ spScreen->hover.active ())
242+ {
243+ GLTexture* spinner = NULL;
244+
245+ if (!spScreen->dndSpinners.empty ())
246+ {
247+ int speed = spScreen->optionGetDndTimeoutSpinnerSpeed ();
248+ unsigned dndSpinnerIdx = (spScreen->hover.minTime() - spScreen->hover.minLeft()) / speed;
249+ const GLTexture::List& tex_list = spScreen->dndSpinners[dndSpinnerIdx % spScreen->dndSpinners.size()];
250+ spinner = tex_list.empty() ? NULL : tex_list.front();
251+ }
252+
253+ if (spinner)
254+ {
255+ float scale;
256+ int x, y;
257+ int size;
258+ int scaledWinWidth, scaledWinHeight;
259+ int spinnerMaxSize = spinner->width();
260+
261+ scaledWinWidth = priv->window->width () * priv->scale;
262+ scaledWinHeight = priv->window->height () * priv->scale;
263+
264+ size = MIN (spinnerMaxSize, MIN (scaledWinWidth, scaledWinHeight));
265+ x = priv->tx + priv->window->x () + (scaledWinWidth - size) / 2;
266+ y = priv->ty + priv->window->y () + (scaledWinHeight - size) / 2;
267+ scale = 1.0;
268+
269+ if (size != spinnerMaxSize)
270+ {
271+ size = spinnerMaxSize;
272+ scale = MIN (scaledWinWidth, scaledWinHeight) / (float) spinnerMaxSize;
273+ }
274+
275+ priv->cWindow->addDamageRect (CompRect (x, y, size / scale, size / scale));
276+
277+ mask |= PAINT_WINDOW_BLEND_MASK;
278+
279+ CompRegion iconReg (0, 0, size, size);
280+ GLTexture::MatrixList ml (1);
281+
282+ ml[0] = spinner->matrix ();
283+ priv->gWindow->vertexBuffer ()->begin ();
284+
285+ if (size)
286+ priv->gWindow->glAddGeometry (ml, iconReg, iconReg);
287+
288+ if (priv->gWindow->vertexBuffer ()->end ())
289+ {
290+ GLMatrix wTransform (transform);
291+ GLWindowPaintAttrib sAttrib (attrib);
292+
293+ wTransform.scale (scale, scale, 1.0f);
294+ wTransform.translate (x / scale, y / scale, 0.0f);
295+ sAttrib.brightness *= 0.65f;
296+
297+ priv->gWindow->glDrawTexture (spinner, wTransform, sAttrib, mask);
298+ }
299+ }
300+ }
301 }
302
303 bool
304@@ -924,6 +988,7 @@
305 activateEvent (false);
306 state = ScaleScreen::Idle;
307
308+ screen->handleEventSetEnabled (this, false);
309 cScreen->preparePaintSetEnabled (this, false);
310 cScreen->donePaintSetEnabled (this, false);
311 gScreen->glPaintOutputSetEnabled (this, false);
312@@ -982,7 +1047,7 @@
313 }
314
315 void
316-PrivateScaleScreen::sendDndStatusMessage (Window source)
317+PrivateScaleScreen::sendDndStatusMessage (Window source, bool asks)
318 {
319 XEvent xev;
320
321@@ -994,11 +1059,36 @@
322 xev.xclient.window = source;
323
324 xev.xclient.data.l[0] = dndTarget;
325- xev.xclient.data.l[1] = 2;
326+ xev.xclient.data.l[1] = 0;
327 xev.xclient.data.l[2] = 0;
328 xev.xclient.data.l[3] = 0;
329 xev.xclient.data.l[4] = None;
330
331+ if (asks)
332+ {
333+ xev.xclient.data.l[1] = 1 << 0 | 1 << 1;
334+ xev.xclient.data.l[4] = xdndActionAsk;
335+ }
336+
337+ XSendEvent (screen->dpy (), source, false, 0, &xev);
338+}
339+
340+void
341+PrivateScaleScreen::sendDndFinishedMessage (Window source)
342+{
343+ XEvent xev;
344+
345+ xev.xclient.type = ClientMessage;
346+ xev.xclient.display = screen->dpy ();
347+ xev.xclient.format = 32;
348+
349+ xev.xclient.message_type = xdndFinished;
350+ xev.xclient.window = source;
351+
352+ xev.xclient.data.l[0] = dndTarget;
353+ xev.xclient.data.l[1] = 0; // Not accepted
354+ xev.xclient.data.l[2] = None;
355+
356 XSendEvent (screen->dpy (), source, false, 0, &xev);
357 }
358
359@@ -1037,7 +1127,10 @@
360 }
361
362 if (ss->priv->dndTarget)
363+ {
364+ ss->priv->dndCheck.stop ();
365 XUnmapWindow (::screen->dpy (), ss->priv->dndTarget);
366+ }
367
368 ss->priv->grab = false;
369
370@@ -1103,9 +1196,9 @@
371 if (!dndTarget)
372 {
373 XSetWindowAttributes attr;
374- long xdndVersion = 3;
375+ long xdndVersion = 5;
376
377- attr.override_redirect = true;
378+ attr.override_redirect = True;
379
380 dndTarget = XCreateWindow (screen->dpy (), screen->root (),
381 0, 0, 1, 1, 0, CopyFromParent,
382@@ -1118,9 +1211,20 @@
383 (unsigned char *) &xdndVersion, 1);
384 }
385
386+ if (screen->XShape ())
387+ {
388+ CompRegion workAreaRegion;
389+
390+ foreach (const CompOutput& output, screen->outputDevs ())
391+ workAreaRegion |= output.workArea ();
392+
393+ XShapeCombineRegion (screen->dpy (), dndTarget, ShapeBounding, 0, 0, workAreaRegion.handle (), ShapeSet);
394+ }
395+
396 XMoveResizeWindow (screen->dpy (), dndTarget,
397 0, 0, screen->width (), screen->height ());
398 XMapRaised (screen->dpy (), dndTarget);
399+ XSync (screen->dpy (), False);
400
401 return true;
402 }
403@@ -1212,7 +1316,7 @@
404 }
405 else if (!grabIndex)
406 {
407- grabIndex = screen->pushGrab (cursor, "scale");
408+ grabIndex = screen->pushGrab (screen->normalCursor (), "scale");
409 if (grabIndex)
410 grab = true;
411 }
412@@ -1249,6 +1353,7 @@
413
414 cScreen->damageScreen ();
415
416+ screen->handleEventSetEnabled (this, true);
417 cScreen->preparePaintSetEnabled (this, true);
418 cScreen->donePaintSetEnabled (this, true);
419 gScreen->glPaintOutputSetEnabled (this, true);
420@@ -1531,35 +1636,34 @@
421 }
422 else
423 {
424- CompOption::Vector o (0);
425- CompAction *action;
426-
427 /* terminate scale mode if the recently closed
428 * window was the last scaled window */
429-
430- o.push_back (CompOption ("root", CompOption::TypeInt));
431- o[0].value ().set ((int) screen->root ());
432-
433- action = &optionGetInitiateEdge ();
434- scaleTerminate (action, CompAction::StateCancel, o);
435-
436- action = &optionGetInitiateKey ();
437- scaleTerminate (action, CompAction::StateCancel, o);
438+ terminateScale (false);
439 break;
440 }
441 }
442 }
443 }
444
445+void PrivateScaleScreen::terminateScale (bool accept)
446+{
447+ CompOption::Vector o (0);
448+
449+ o.push_back (CompOption ("root", CompOption::TypeInt));
450+ o[0].value ().set ((int) screen->root ());
451+
452+ scaleTerminate (&optionGetInitiateEdge (), accept ? 0 : CompAction::StateCancel, o);
453+ scaleTerminate (&optionGetInitiateKey (), accept ? 0 : CompAction::StateCancel, o);
454+
455+ activateEvent (false);
456+}
457+
458 bool
459 PrivateScaleScreen::hoverTimeout ()
460 {
461 if (grab && state != ScaleScreen::In)
462 {
463- CompWindow *w;
464- CompOption::Vector o (0);
465-
466- w = screen->findWindow (selectedWindow);
467+ CompWindow *w = screen->findWindow (selectedWindow);
468 if (w)
469 {
470 lastActiveNum = w->activeNum ();
471@@ -1568,13 +1672,39 @@
472 w->moveInputFocusTo ();
473 }
474
475- o.push_back (CompOption ("root", CompOption::TypeInt));
476- o[0].value ().set ((int) screen->root ());
477-
478- scaleTerminate (&optionGetInitiateEdge (), 0, o);
479- scaleTerminate (&optionGetInitiateKey (), 0, o);
480- }
481-
482+ terminateScale (true);
483+ }
484+
485+ return false;
486+}
487+
488+bool
489+PrivateScaleScreen::dndCheckTimeout ()
490+{
491+ if (!dndTarget)
492+ return false;
493+
494+ CompWindow *w = screen->findWindow (dndTarget);
495+
496+ if (!w || !w->isMapped ())
497+ return false;
498+
499+ Window drag_owner = XGetSelectionOwner (screen->dpy (), xdndSelection);
500+
501+ if (drag_owner)
502+ {
503+ // evil hack because some apps (Qt) don't release the selection owner on drag finished
504+ Window root_r, child_r;
505+ int root_x_r, root_y_r, win_x_r, win_y_r;
506+ unsigned int mask;
507+ XQueryPointer (screen->dpy (), screen->root (), &root_r, &child_r,
508+ &root_x_r, &root_y_r, &win_x_r, &win_y_r, &mask);
509+
510+ if (mask & (Button1Mask | Button2Mask | Button3Mask))
511+ return true;
512+ }
513+
514+ terminateScale (false);
515 return false;
516 }
517
518@@ -1606,46 +1736,29 @@
519 state != ScaleScreen::In)
520 {
521 XButtonEvent *button = &event->xbutton;
522- CompOption::Vector o (0);
523-
524- o.push_back (CompOption ("root", CompOption::TypeInt));
525- o[0].value ().set ((int) screen->root ());
526
527 /* Button1 terminates scale mode, other buttons can select
528 * windows */
529- if (selectWindowAt (button->x_root, button->y_root, true) &&
530- event->xbutton.button == Button1)
531- {
532- scaleTerminate (&optionGetInitiateEdge (), 0, o);
533- scaleTerminate (&optionGetInitiateKey (), 0, o);
534- }
535- else if (optionGetClickOnDesktop () == 1 &&
536- event->xbutton.button == Button1)
537- {
538- CompPoint pointer (button->x_root, button->y_root);
539- CompRect workArea (screen->workArea ());
540- workArea.setX (workArea.x() + optionGetXOffset ());
541- workArea.setY (workArea.y() + optionGetYOffset ());
542-
543- if (workArea.contains (pointer))
544- {
545- scaleTerminate (&optionGetInitiateEdge (), 0, o);
546- scaleTerminate (&optionGetInitiateKey (), 0, o);
547- screen->enterShowDesktopMode ();
548- }
549- }
550- else if (optionGetClickOnDesktop () == 2 &&
551- event->xbutton.button == Button1)
552- {
553- CompPoint pointer (button->x_root, button->y_root);
554- CompRect workArea (screen->workArea ());
555- workArea.setX (workArea.x() + optionGetXOffset ());
556- workArea.setY (workArea.y() + optionGetYOffset ());
557-
558- if (workArea.contains (pointer))
559- {
560- scaleTerminate (&optionGetInitiateEdge (), 0, o);
561- scaleTerminate (&optionGetInitiateKey (), 0, o);
562+ if (event->xbutton.button != Button1)
563+ break;
564+
565+ if (selectWindowAt (button->x_root, button->y_root, true))
566+ {
567+ terminateScale (true);
568+ }
569+ else if (optionGetClickOnDesktop () != ScaleOptions::ClickOnDesktopNone)
570+ {
571+ CompPoint pointer (button->x_root, button->y_root);
572+ CompRect workArea (screen->workArea ());
573+ workArea.setX (workArea.x() + optionGetXOffset ());
574+ workArea.setY (workArea.y() + optionGetYOffset ());
575+
576+ if (workArea.contains (pointer))
577+ {
578+ terminateScale (false);
579+
580+ if (optionGetClickOnDesktop () == ScaleOptions::ClickOnDesktopShowDesktop)
581+ screen->enterShowDesktopMode ();
582 }
583 }
584 }
585@@ -1669,33 +1782,31 @@
586 w = screen->findWindow (event->xdestroywindow.window);
587 break;
588 case UnmapNotify:
589-
590 w = screen->findWindow (event->xunmap.window);
591 break;
592 case ClientMessage:
593 if (event->xclient.message_type == Atoms::xdndPosition)
594 {
595- w = screen->findWindow (event->xclient.window);
596- if (w)
597+ if (event->xclient.window == dndTarget)
598 {
599- if (w->id () == dndTarget)
600- sendDndStatusMessage (event->xclient.data.l[0]);
601+ bool acceptsDnd = false;
602
603- if (grab &&
604- state != ScaleScreen::In &&
605- w->id () == dndTarget)
606+ if (grab && state != ScaleScreen::In)
607 {
608+ dndCheck.stop ();
609+
610 ScaleWindow *sw = checkForWindowAt (pointerX, pointerY);
611 if (sw && sw->priv->isScaleWin ())
612 {
613 int time;
614
615 time = optionGetHoverTime ();
616+ acceptsDnd = true;
617
618 if (hover.active ())
619 {
620 int lastMotion = sqrt (pow (pointerX - lastPointerX, 2) + pow (pointerY - lastPointerY, 2));
621-
622+
623 if (sw->window->id () != selectedWindow || lastMotion > optionGetDndDistance ())
624 hover.stop ();
625 }
626@@ -1713,24 +1824,35 @@
627 hover.stop ();
628 }
629 }
630- }
631- }
632- else if (event->xclient.message_type == Atoms::xdndDrop ||
633- event->xclient.message_type == Atoms::xdndLeave)
634- {
635- w = screen->findWindow (event->xclient.window);
636- if (w)
637- {
638- if (grab &&
639- state != ScaleScreen::In &&
640- w->id () == dndTarget)
641+
642+ sendDndStatusMessage (event->xclient.data.l[0], acceptsDnd);
643+ }
644+ }
645+ else if (event->xclient.message_type == Atoms::xdndEnter)
646+ {
647+ if (event->xclient.window == dndTarget &&
648+ grab && state != ScaleScreen::In)
649+ {
650+ dndCheck.stop ();
651+ }
652+ }
653+ else if (event->xclient.message_type == Atoms::xdndLeave)
654+ {
655+ if (event->xclient.window == dndTarget &&
656+ grab && state != ScaleScreen::In)
657+ {
658+ dndCheck.start ();
659+ }
660+ }
661+ else if (event->xclient.message_type == Atoms::xdndDrop)
662+ {
663+ if (event->xclient.window == dndTarget)
664+ {
665+ sendDndFinishedMessage (event->xclient.data.l[0]);
666+
667+ if (grab && state != ScaleScreen::In)
668 {
669- CompOption::Vector o (0);
670- o.push_back (CompOption ("root", CompOption::TypeInt));
671- o[0].value ().set ((int) screen->root ());
672-
673- scaleTerminate (&optionGetInitiateEdge (), 0, o);
674- scaleTerminate (&optionGetInitiateKey (), 0, o);
675+ terminateScale (true);
676 }
677 }
678 }
679@@ -1746,6 +1868,7 @@
680
681 switch (event->type) {
682 case UnmapNotify:
683+ dndCheck.start ();
684 if (w)
685 windowRemove (w);
686 break;
687@@ -1832,9 +1955,11 @@
688 grab (false),
689 grabIndex (0),
690 dndTarget (None),
691+ xdndSelection (XInternAtom (screen->dpy (), "XdndSelection", False)),
692+ xdndFinished (XInternAtom (screen->dpy (), "XdndFinished", False)),
693+ xdndActionAsk (XInternAtom (screen->dpy (), "XdndActionAsk", False)),
694 state (ScaleScreen::Idle),
695 moreAdjust (false),
696- cursor (0),
697 nSlots (0)
698 {
699 leftKeyCode = XKeysymToKeycode (screen->dpy (), XStringToKeysym ("Left"));
700@@ -1842,11 +1967,11 @@
701 upKeyCode = XKeysymToKeycode (screen->dpy (), XStringToKeysym ("Up"));
702 downKeyCode = XKeysymToKeycode (screen->dpy (), XStringToKeysym ("Down"));
703
704- cursor = XCreateFontCursor (screen->dpy (), XC_left_ptr);
705-
706 opacity = (OPAQUE * optionGetOpacity ()) / 100;
707
708 hover.setCallback (boost::bind (&PrivateScaleScreen::hoverTimeout, this));
709+ dndCheck.setCallback (boost::bind (&PrivateScaleScreen::dndCheckTimeout, this));
710+ dndCheck.setTimes (200);
711
712 optionSetOpacityNotify (boost::bind (&PrivateScaleScreen::updateOpacity, this));
713
714@@ -1883,15 +2008,35 @@
715
716 #undef SCALEBIND
717
718+ CompString pluginName("scale");
719+ CompSize size;
720+ CompString file;
721+
722+ file = "dnd-spinner-000.png";
723+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
724+ file = "dnd-spinner-125.png";
725+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
726+ file = "dnd-spinner-250.png";
727+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
728+ file = "dnd-spinner-375.png";
729+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
730+ file = "dnd-spinner-500.png";
731+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
732+ file = "dnd-spinner-625.png";
733+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
734+ file = "dnd-spinner-750.png";
735+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
736+ file = "dnd-spinner-875.png";
737+ dndSpinners.push_back(GLTexture::readImageToTexture(file, pluginName, size));
738+
739 ScreenInterface::setHandler (s);
740 CompositeScreenInterface::setHandler (cScreen, false);
741 GLScreenInterface::setHandler (gScreen, false);
742-}
743
744-PrivateScaleScreen::~PrivateScaleScreen ()
745-{
746- if (cursor)
747- XFreeCursor (screen->dpy (), cursor);
748+ screen->handleEventSetEnabled (this, false);
749+ cScreen->preparePaintSetEnabled (this, false);
750+ cScreen->donePaintSetEnabled (this, false);
751+ gScreen->glPaintOutputSetEnabled (this, false);
752 }
753
754 void

Subscribers

People subscribed via source and target branches

to all changes: