~om26er/ubuntu/oneiric/unity/sru-778256

« back to all changes in this revision

Viewing changes to plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp

  • Committer: Didier Roche
  • Date: 2011-07-21 16:17:59 UTC
  • mfrom: (55.813.3 upstream)
  • Revision ID: didier.roche@canonical.com-20110721161759-osmh94x428t2bf2b
* New upstream release.
* debian/control:
  - build-dep on libnotify-dev
  - bump libnux-1.0-dev dep for ABI break

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#define NUM_HANDLES 9
23
23
#define FADE_MSEC UnityMTGrabHandlesScreen::get (screen)->optionGetFadeDuration ()
24
24
 
25
 
COMPIZ_PLUGIN_20090315 (unitymtgrabhandles, UnityMTGrabHandlesPluginVTable);
26
 
 
27
 
void
28
 
Unity::MT::GrabHandle::reposition (CompPoint *p, bool hard)
29
 
{
30
 
    XWindowChanges xwc;
31
 
    unsigned int   vm = 0;
32
 
 
33
 
    UMTGH_SCREEN (screen);
34
 
 
35
 
    us->cScreen->damageRegion ((CompRect &) *this);
36
 
 
37
 
    if (p)
38
 
    {
39
 
        setX (p->x ());
40
 
        setY (p->y ());
41
 
 
42
 
        xwc.x = x ();
43
 
        xwc.y = y ();
44
 
 
45
 
        vm |= (CWX | CWY);
46
 
    }
47
 
 
48
 
    vm |= (CWStackMode | CWSibling);
49
 
 
50
 
    xwc.stack_mode = Above;
51
 
    xwc.sibling = mOwner;
52
 
 
53
 
    if (hard)
54
 
    {
55
 
        XConfigureWindow (screen->dpy (), mIpw, vm, &xwc);
56
 
        XSelectInput (screen->dpy (), mIpw, ButtonPressMask | ButtonReleaseMask);
57
 
    }
58
 
 
59
 
    us->cScreen->damageRegion ((CompRect &) *this);
60
 
}
61
 
 
62
 
void
63
 
Unity::MT::GrabHandle::hide ()
64
 
{
65
 
    if (mIpw)
66
 
        XUnmapWindow (screen->dpy (), mIpw);
67
 
}
68
 
 
69
 
void
70
 
Unity::MT::GrabHandle::show ()
71
 
{
72
 
    if (!mIpw)
73
 
    {
74
 
        XSetWindowAttributes xswa;
75
 
 
76
 
        xswa.override_redirect = TRUE;
77
 
 
78
 
        mIpw = XCreateWindow (screen->dpy (),
79
 
                              screen->root (),
80
 
                              -100, -100,
81
 
                              mTexture->second.width (),
82
 
                              mTexture->second.height (),
83
 
                              0,
84
 
                              CopyFromParent, InputOnly,
85
 
                              CopyFromParent, CWOverrideRedirect, &xswa);
86
 
 
87
 
        UnityMTGrabHandlesScreen::get (screen)->addHandleWindow (this, mIpw);
88
 
 
89
 
        reposition (NULL, true);
90
 
    }
91
 
 
92
 
    XMapWindow (screen->dpy (), mIpw);
 
25
COMPIZ_PLUGIN_20090315(unitymtgrabhandles, UnityMTGrabHandlesPluginVTable);
 
26
 
 
27
void
 
28
Unity::MT::GrabHandle::reposition(CompPoint* p, bool hard)
 
29
{
 
30
  XWindowChanges xwc;
 
31
  unsigned int   vm = 0;
 
32
 
 
33
  UMTGH_SCREEN(screen);
 
34
 
 
35
  us->cScreen->damageRegion((CompRect&) *this);
 
36
 
 
37
  if (p)
 
38
  {
 
39
    setX(p->x());
 
40
    setY(p->y());
 
41
 
 
42
    xwc.x = x();
 
43
    xwc.y = y();
 
44
 
 
45
    vm |= (CWX | CWY);
 
46
  }
 
47
 
 
48
  vm |= (CWStackMode | CWSibling);
 
49
 
 
50
  xwc.stack_mode = Above;
 
51
  xwc.sibling = mOwner;
 
52
 
 
53
  if (hard)
 
54
  {
 
55
    XConfigureWindow(screen->dpy(), mIpw, vm, &xwc);
 
56
    XSelectInput(screen->dpy(), mIpw, ButtonPressMask | ButtonReleaseMask);
 
57
  }
 
58
 
 
59
  us->cScreen->damageRegion((CompRect&) *this);
 
60
}
 
61
 
 
62
void
 
63
Unity::MT::GrabHandle::hide()
 
64
{
 
65
  if (mIpw)
 
66
    XUnmapWindow(screen->dpy(), mIpw);
 
67
}
 
68
 
 
69
void
 
70
Unity::MT::GrabHandle::show()
 
71
{
 
72
  if (!mIpw)
 
73
  {
 
74
    XSetWindowAttributes xswa;
 
75
 
 
76
    xswa.override_redirect = TRUE;
 
77
 
 
78
    mIpw = XCreateWindow(screen->dpy(),
 
79
                         screen->root(),
 
80
                         -100, -100,
 
81
                         mTexture->second.width(),
 
82
                         mTexture->second.height(),
 
83
                         0,
 
84
                         CopyFromParent, InputOnly,
 
85
                         CopyFromParent, CWOverrideRedirect, &xswa);
 
86
 
 
87
    UnityMTGrabHandlesScreen::get(screen)->addHandleWindow(this, mIpw);
 
88
 
 
89
    reposition(NULL, true);
 
90
  }
 
91
 
 
92
  XMapWindow(screen->dpy(), mIpw);
93
93
}
94
94
 
95
95
Unity::MT::TextureLayout
96
 
Unity::MT::GrabHandle::layout ()
97
 
{
98
 
    return TextureLayout (&mTexture->first, (CompRect *) this);
99
 
}
100
 
 
101
 
Unity::MT::GrabHandle::GrabHandle (TextureSize *t, Window owner, unsigned int id) :
102
 
    mIpw (0),
103
 
    mOwner (owner),
104
 
    mTexture (t),
105
 
    mId (id)
106
 
{
107
 
    setX (0);
108
 
    setY (0);
109
 
    setSize (t->second);
110
 
}
111
 
 
112
 
Unity::MT::GrabHandle::~GrabHandle ()
113
 
{
114
 
    if (mIpw)
115
 
    {
116
 
        UnityMTGrabHandlesScreen::get (screen)->removeHandleWindow (mIpw);
117
 
 
118
 
        XDestroyWindow (screen->dpy (), mIpw);
119
 
    }
120
 
}
121
 
 
122
 
void
123
 
Unity::MT::GrabHandle::handleButtonPress (XButtonEvent *be)
124
 
{
125
 
    /* Send _NET_MOVERESIZE to root window so that a button-1
126
 
     * press on this window will start resizing the window around */
127
 
    XEvent     event;
128
 
    CompWindow *w;
129
 
    w = screen->findTopLevelWindow (mOwner, false);
130
 
 
131
 
    if (!w)
132
 
        return;
133
 
    
134
 
    if (screen->getOption ("raise_on_click"))
135
 
        w->updateAttributes (CompStackingUpdateModeAboveFullscreen);
136
 
 
137
 
    if (w->id () != screen->activeWindow ())
138
 
        if (w->focus ())
139
 
            w->moveInputFocusTo ();
140
 
 
141
 
    event.xclient.type    = ClientMessage;
142
 
    event.xclient.display = screen->dpy ();
143
 
 
144
 
    event.xclient.serial          = 0;
145
 
    event.xclient.send_event      = true;
146
 
 
147
 
    /* FIXME: Need to call findWindow since we need to send the
148
 
     * _NET_WM_MOVERESIZE request to the client not the frame
149
 
     * which we are tracking. That's a bit shitty */
150
 
    event.xclient.window            = w->id ();
151
 
    event.xclient.message_type      = Atoms::wmMoveResize;
152
 
    event.xclient.format            = 32;
153
 
 
154
 
    event.xclient.data.l[0] = be->x_root;
155
 
    event.xclient.data.l[1] = be->y_root;
156
 
    event.xclient.data.l[2] = mId;
157
 
    event.xclient.data.l[3] = be->button;
158
 
    event.xclient.data.l[4] = 1;
159
 
 
160
 
    XSendEvent (screen->dpy (), screen->root (), false,
161
 
            SubstructureRedirectMask | SubstructureNotifyMask,
162
 
            &event);
163
 
}
164
 
 
165
 
void
166
 
Unity::MT::GrabHandleGroup::show ()
167
 
{
168
 
    foreach (Unity::MT::GrabHandle &handle, *this)
169
 
        handle.show ();
170
 
 
171
 
    mState = FADE_IN;
172
 
}
173
 
 
174
 
void
175
 
Unity::MT::GrabHandleGroup::hide ()
176
 
{
177
 
    foreach (Unity::MT::GrabHandle &handle, *this)
178
 
        handle.hide ();
179
 
 
180
 
    mState = FADE_OUT;
 
96
Unity::MT::GrabHandle::layout()
 
97
{
 
98
  return TextureLayout(&mTexture->first, (CompRect*) this);
 
99
}
 
100
 
 
101
Unity::MT::GrabHandle::GrabHandle(TextureSize* t, Window owner, unsigned int id) :
 
102
  mIpw(0),
 
103
  mOwner(owner),
 
104
  mTexture(t),
 
105
  mId(id)
 
106
{
 
107
  setX(0);
 
108
  setY(0);
 
109
  setSize(t->second);
 
110
}
 
111
 
 
112
Unity::MT::GrabHandle::~GrabHandle()
 
113
{
 
114
  if (mIpw)
 
115
  {
 
116
    UnityMTGrabHandlesScreen::get(screen)->removeHandleWindow(mIpw);
 
117
 
 
118
    XDestroyWindow(screen->dpy(), mIpw);
 
119
  }
 
120
}
 
121
 
 
122
void
 
123
Unity::MT::GrabHandle::handleButtonPress(XButtonEvent* be)
 
124
{
 
125
  /* Send _NET_MOVERESIZE to root window so that a button-1
 
126
   * press on this window will start resizing the window around */
 
127
  XEvent     event;
 
128
  CompWindow* w;
 
129
  w = screen->findTopLevelWindow(mOwner, false);
 
130
 
 
131
  if (!w)
 
132
    return;
 
133
 
 
134
  if (screen->getOption("raise_on_click"))
 
135
    w->updateAttributes(CompStackingUpdateModeAboveFullscreen);
 
136
 
 
137
  if (w->id() != screen->activeWindow())
 
138
    if (w->focus())
 
139
      w->moveInputFocusTo();
 
140
 
 
141
  event.xclient.type    = ClientMessage;
 
142
  event.xclient.display = screen->dpy();
 
143
 
 
144
  event.xclient.serial    = 0;
 
145
  event.xclient.send_event    = true;
 
146
 
 
147
  /* FIXME: Need to call findWindow since we need to send the
 
148
   * _NET_WM_MOVERESIZE request to the client not the frame
 
149
   * which we are tracking. That's a bit shitty */
 
150
  event.xclient.window      = w->id();
 
151
  event.xclient.message_type      = Atoms::wmMoveResize;
 
152
  event.xclient.format      = 32;
 
153
 
 
154
  event.xclient.data.l[0] = be->x_root;
 
155
  event.xclient.data.l[1] = be->y_root;
 
156
  event.xclient.data.l[2] = mId;
 
157
  event.xclient.data.l[3] = be->button;
 
158
  event.xclient.data.l[4] = 1;
 
159
 
 
160
  XSendEvent(screen->dpy(), screen->root(), false,
 
161
             SubstructureRedirectMask | SubstructureNotifyMask,
 
162
             &event);
 
163
}
 
164
 
 
165
void
 
166
Unity::MT::GrabHandleGroup::show()
 
167
{
 
168
  foreach(Unity::MT::GrabHandle & handle, *this)
 
169
  handle.show();
 
170
 
 
171
  mState = FADE_IN;
 
172
}
 
173
 
 
174
void
 
175
Unity::MT::GrabHandleGroup::hide()
 
176
{
 
177
  foreach(Unity::MT::GrabHandle & handle, *this)
 
178
  handle.hide();
 
179
 
 
180
  mState = FADE_OUT;
181
181
}
182
182
 
183
183
bool
184
 
Unity::MT::GrabHandleGroup::animate (unsigned int msec)
 
184
Unity::MT::GrabHandleGroup::animate(unsigned int msec)
185
185
{
186
 
    mMoreAnimate = false;
187
 
 
188
 
    switch (mState)
189
 
    {
190
 
        case FADE_IN:
191
 
 
192
 
            mOpacity += ((float) msec / (float) FADE_MSEC) * OPAQUE;
193
 
 
194
 
            if (mOpacity >= OPAQUE)
195
 
            {
196
 
                mOpacity = OPAQUE;
197
 
                mState = NONE;
198
 
            }
199
 
            break;
200
 
        case FADE_OUT:
201
 
            mOpacity -= ((float) msec / (float) FADE_MSEC) * OPAQUE;
202
 
 
203
 
            if (mOpacity <= 0)
204
 
            {
205
 
                mOpacity = 0;
206
 
                mState = NONE;
207
 
            }
208
 
            break;
209
 
        default:
210
 
            break;
211
 
    }
212
 
 
213
 
    mMoreAnimate = mState != NONE;
214
 
 
215
 
    return mMoreAnimate;
 
186
  mMoreAnimate = false;
 
187
 
 
188
  switch (mState)
 
189
  {
 
190
    case FADE_IN:
 
191
 
 
192
      mOpacity += ((float) msec / (float) FADE_MSEC) * OPAQUE;
 
193
 
 
194
      if (mOpacity >= OPAQUE)
 
195
      {
 
196
        mOpacity = OPAQUE;
 
197
        mState = NONE;
 
198
      }
 
199
      break;
 
200
    case FADE_OUT:
 
201
      mOpacity -= ((float) msec / (float) FADE_MSEC) * OPAQUE;
 
202
 
 
203
      if (mOpacity <= 0)
 
204
      {
 
205
        mOpacity = 0;
 
206
        mState = NONE;
 
207
      }
 
208
      break;
 
209
    default:
 
210
      break;
 
211
  }
 
212
 
 
213
  mMoreAnimate = mState != NONE;
 
214
 
 
215
  return mMoreAnimate;
216
216
}
217
217
 
218
218
int
219
 
Unity::MT::GrabHandleGroup::opacity ()
220
 
{
221
 
    return mOpacity;
222
 
}
223
 
 
224
 
bool
225
 
Unity::MT::GrabHandleGroup::visible ()
226
 
{
227
 
    return mOpacity > 0.0f;
228
 
}
229
 
 
230
 
bool
231
 
Unity::MT::GrabHandleGroup::needsAnimate ()
232
 
{
233
 
    return mMoreAnimate;
 
219
Unity::MT::GrabHandleGroup::opacity()
 
220
{
 
221
  return mOpacity;
 
222
}
 
223
 
 
224
bool
 
225
Unity::MT::GrabHandleGroup::visible()
 
226
{
 
227
  return mOpacity > 0.0f;
 
228
}
 
229
 
 
230
bool
 
231
Unity::MT::GrabHandleGroup::needsAnimate()
 
232
{
 
233
  return mMoreAnimate;
234
234
}
235
235
 
236
236
void
237
 
Unity::MT::GrabHandleGroup::relayout (const CompRect &rect, bool hard)
238
 
{
239
 
    /* Each grab handle at each vertex, eg:
240
 
     *
241
 
     * 1 - topleft
242
 
     * 2 - top
243
 
     * 3 - topright
244
 
     * 4 - right
245
 
     * 5 - bottom-right
246
 
     * 6 - bottom
247
 
     * 7 - bottom-left
248
 
     * 8 - left
249
 
     */
250
 
 
251
 
    const float pos[9][2] = {
252
 
        {0.0f, 0.0f}, {0.5f, 0.0f}, {1.0f, 0.0f},
253
 
        {1.0f, 0.5f}, {1.0f, 1.0f},
254
 
        {0.5f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.5f},
255
 
        {0.5f, 0.5f} /* middle */
256
 
    };
257
 
 
258
 
    for (unsigned int i = 0; i < NUM_HANDLES; i++)
259
 
    {
260
 
        Unity::MT::GrabHandle &handle = at (i);
261
 
        CompPoint p  (rect.x () + rect.width () * pos[i][0] -
262
 
                      handle.width () / 2,
263
 
                      rect.y () + rect.height () * pos[i][1] -
264
 
                      handle.height () / 2);
265
 
 
266
 
        handle.reposition (&p, hard);
267
 
    }
268
 
}
269
 
 
270
 
Unity::MT::GrabHandleGroup::GrabHandleGroup (Window owner) :
271
 
    mState (NONE),
272
 
    mOpacity (0.0f),
273
 
    mMoreAnimate (false)
274
 
{
275
 
    UMTGH_SCREEN (screen);
276
 
 
277
 
    for (unsigned int i = 0; i < NUM_HANDLES; i++)
278
 
        push_back (Unity::MT::GrabHandle (&us->textures ().at (i), owner, i));
279
 
}
280
 
 
281
 
Unity::MT::GrabHandleGroup::~GrabHandleGroup ()
282
 
{
283
 
    UMTGH_SCREEN (screen);
284
 
 
285
 
    foreach (Unity::MT::GrabHandle &handle, *this)
286
 
        us->cScreen->damageRegion ((CompRect &) handle);
 
237
Unity::MT::GrabHandleGroup::relayout(const CompRect& rect, bool hard)
 
238
{
 
239
  /* Each grab handle at each vertex, eg:
 
240
   *
 
241
   * 1 - topleft
 
242
   * 2 - top
 
243
   * 3 - topright
 
244
   * 4 - right
 
245
   * 5 - bottom-right
 
246
   * 6 - bottom
 
247
   * 7 - bottom-left
 
248
   * 8 - left
 
249
   */
 
250
 
 
251
  const float pos[9][2] =
 
252
  {
 
253
    {0.0f, 0.0f}, {0.5f, 0.0f}, {1.0f, 0.0f},
 
254
    {1.0f, 0.5f}, {1.0f, 1.0f},
 
255
    {0.5f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.5f},
 
256
    {0.5f, 0.5f} /* middle */
 
257
  };
 
258
 
 
259
  for (unsigned int i = 0; i < NUM_HANDLES; i++)
 
260
  {
 
261
    Unity::MT::GrabHandle& handle = at(i);
 
262
    CompPoint p(rect.x() + rect.width() * pos[i][0] -
 
263
                handle.width() / 2,
 
264
                rect.y() + rect.height() * pos[i][1] -
 
265
                handle.height() / 2);
 
266
 
 
267
    handle.reposition(&p, hard);
 
268
  }
 
269
}
 
270
 
 
271
Unity::MT::GrabHandleGroup::GrabHandleGroup(Window owner) :
 
272
  mState(NONE),
 
273
  mOpacity(0.0f),
 
274
  mMoreAnimate(false)
 
275
{
 
276
  UMTGH_SCREEN(screen);
 
277
 
 
278
  for (unsigned int i = 0; i < NUM_HANDLES; i++)
 
279
    push_back(Unity::MT::GrabHandle(&us->textures().at(i), owner, i));
 
280
}
 
281
 
 
282
Unity::MT::GrabHandleGroup::~GrabHandleGroup()
 
283
{
 
284
  UMTGH_SCREEN(screen);
 
285
 
 
286
  foreach(Unity::MT::GrabHandle & handle, *this)
 
287
  us->cScreen->damageRegion((CompRect&) handle);
287
288
}
288
289
 
289
290
std::vector <Unity::MT::TextureLayout>
290
 
Unity::MT::GrabHandleGroup::layout ()
 
291
Unity::MT::GrabHandleGroup::layout()
291
292
{
292
 
    std::vector <Unity::MT::TextureLayout> layout;
293
 
 
294
 
    foreach (Unity::MT::GrabHandle &handle, *this)
295
 
        layout.push_back (handle.layout ());
296
 
 
297
 
    return layout;
 
293
  std::vector <Unity::MT::TextureLayout> layout;
 
294
 
 
295
  foreach(Unity::MT::GrabHandle & handle, *this)
 
296
  layout.push_back(handle.layout());
 
297
 
 
298
  return layout;
298
299
}
299
300
 
300
301
/* Super speed hack */
301
302
static bool
302
 
sortPointers (const CompWindow *p1, const CompWindow *p2)
 
303
sortPointers(const CompWindow* p1, const CompWindow* p2)
303
304
{
304
 
    return (void *) p1 < (void *) p2;
 
305
  return (void*) p1 < (void*) p2;
305
306
}
306
307
 
307
308
void
308
 
UnityMTGrabHandlesScreen::handleEvent (XEvent *event)
 
309
UnityMTGrabHandlesScreen::handleEvent(XEvent* event)
309
310
{
310
 
    Unity::MT::GrabHandle *handle;
311
 
    std::map <Window, Unity::MT::GrabHandle *>::iterator it;
312
 
    CompWindow *w, *oldPrev, *oldNext;
313
 
 
314
 
    w = oldPrev = oldNext = NULL;
315
 
 
316
 
    switch (event->type)
317
 
    {
318
 
        case FocusIn:
319
 
        case FocusOut:
320
 
            if (event->xfocus.mode == NotifyUngrab)
321
 
            {
322
 
                foreach (CompWindow *w, screen->windows ())
323
 
                {
324
 
                    UnityMTGrabHandlesWindow *mtwindow = UnityMTGrabHandlesWindow::get (w);
325
 
                    if (mtwindow->handleTimerActive ())
326
 
                        mtwindow->resetTimer ();
327
 
                }
328
 
            }
329
 
      break;
330
 
        case ClientMessage:
331
 
 
332
 
            if (event->xclient.message_type == mCompResizeWindowAtom)
 
311
  Unity::MT::GrabHandle* handle;
 
312
  std::map <Window, Unity::MT::GrabHandle*>::iterator it;
 
313
  CompWindow* w, *oldPrev, *oldNext;
 
314
 
 
315
  w = oldPrev = oldNext = NULL;
 
316
 
 
317
  switch (event->type)
 
318
  {
 
319
    case FocusIn:
 
320
    case FocusOut:
 
321
      if (event->xfocus.mode == NotifyUngrab)
 
322
      {
 
323
        foreach(CompWindow * w, screen->windows())
 
324
        {
 
325
          UnityMTGrabHandlesWindow* mtwindow = UnityMTGrabHandlesWindow::get(w);
 
326
          if (mtwindow->handleTimerActive())
 
327
            mtwindow->resetTimer();
 
328
        }
 
329
      }
 
330
      break;
 
331
    case ClientMessage:
 
332
 
 
333
      if (event->xclient.message_type == mCompResizeWindowAtom)
 
334
      {
 
335
        CompWindow* w = screen->findWindow(event->xclient.window);
 
336
 
 
337
        if (w)
 
338
        {
 
339
          CompRect r;
 
340
          UMTGH_WINDOW(w);
 
341
 
 
342
          r.setGeometry(event->xclient.data.l[0] - w->input().left,
 
343
                        event->xclient.data.l[1] - w->input().top,
 
344
                        event->xclient.data.l[2] + w->input().left + w->input().right,
 
345
                        event->xclient.data.l[3] + w->input().top + w->input().bottom);
 
346
 
 
347
          uw->relayout(r, false);
 
348
        }
 
349
      }
 
350
 
 
351
      break;
 
352
 
 
353
    case PropertyNotify:
 
354
 
 
355
      /* Stacking order of managed clients changed, check old
 
356
       * stacking order and ensure stacking of handles
 
357
       * that were changed in the stack */
 
358
 
 
359
 
 
360
      if (event->xproperty.atom == Atoms::clientListStacking)
 
361
      {
 
362
        CompWindowVector       invalidated(0);
 
363
        CompWindowVector       clients = screen->clientList(true);
 
364
        CompWindowVector       oldClients = mLastClientListStacking;
 
365
        CompWindowVector       clientListStacking = screen->clientList(true);
 
366
        /* Windows can be removed and added from the client list
 
367
         * here at the same time (eg hide/unhide launcher ... racy)
 
368
         * so we need to check if the client list contains the same
 
369
         * windows as it used to. Sort both lists and compare ... */
 
370
 
 
371
        std::sort(clients.begin(), clients.end(), sortPointers);
 
372
        std::sort(oldClients.begin(),
 
373
                  oldClients.end(), sortPointers);
 
374
 
 
375
        if (clients != mLastClientListStacking)
 
376
          invalidated = clients;
 
377
        else
 
378
        {
 
379
          CompWindowVector::const_iterator cit = clientListStacking.begin();
 
380
          CompWindowVector::const_iterator oit = mLastClientListStacking.begin();
 
381
 
 
382
          for (; cit != clientListStacking.end(); cit++, oit++)
 
383
          {
 
384
            /* All clients from this point onwards in cit are invalidated
 
385
             * so splice the list to the end of the new client list
 
386
             * and update the stacking of handles there */
 
387
            if ((*cit)->id() != (*oit)->id())
333
388
            {
334
 
                CompWindow *w = screen->findWindow (event->xclient.window);
335
 
 
336
 
                if (w)
337
 
                {
338
 
                    CompRect r;
339
 
                    UMTGH_WINDOW (w);
340
 
 
341
 
                    r.setGeometry (event->xclient.data.l[0] - w->input ().left,
342
 
                                   event->xclient.data.l[1] - w->input ().top,
343
 
                                   event->xclient.data.l[2] + w->input ().left + w->input ().right,
344
 
                                   event->xclient.data.l[3] + w->input ().top + w->input ().bottom);
345
 
 
346
 
                    uw->relayout (r, false);
347
 
                }
 
389
              invalidated.push_back((*cit));
348
390
            }
349
 
 
350
 
            break;
351
 
 
352
 
        case PropertyNotify:
353
 
 
354
 
            /* Stacking order of managed clients changed, check old
355
 
             * stacking order and ensure stacking of handles
356
 
             * that were changed in the stack */
357
 
            
358
 
 
359
 
            if (event->xproperty.atom == Atoms::clientListStacking)
360
 
            {
361
 
                CompWindowVector             invalidated (0);
362
 
                CompWindowVector             clients = screen->clientList (true);
363
 
                CompWindowVector             oldClients = mLastClientListStacking;
364
 
                CompWindowVector             clientListStacking = screen->clientList (true);
365
 
                /* Windows can be removed and added from the client list
366
 
                 * here at the same time (eg hide/unhide launcher ... racy)
367
 
                 * so we need to check if the client list contains the same
368
 
                 * windows as it used to. Sort both lists and compare ... */
369
 
 
370
 
                std::sort (clients.begin (), clients.end (), sortPointers);
371
 
                std::sort (oldClients.begin (),
372
 
                           oldClients.end (), sortPointers);
373
 
 
374
 
                if (clients != mLastClientListStacking)
375
 
                    invalidated = clients;
376
 
                else
377
 
                {
378
 
                    CompWindowVector::const_iterator cit = clientListStacking.begin ();
379
 
                    CompWindowVector::const_iterator oit = mLastClientListStacking.begin ();
380
 
 
381
 
                    for (; cit != clientListStacking.end (); cit++, oit++)
382
 
                    {
383
 
                        /* All clients from this point onwards in cit are invalidated
384
 
                         * so splice the list to the end of the new client list
385
 
                         * and update the stacking of handles there */
386
 
                        if ((*cit)->id () != (*oit)->id ())
387
 
                        {
388
 
                            invalidated.push_back ((*cit));
389
 
                        }
390
 
                    }
391
 
                }
392
 
 
393
 
                foreach (CompWindow *w, invalidated)
394
 
                    UnityMTGrabHandlesWindow::get (w)->restackHandles ();
395
 
 
396
 
                mLastClientListStacking = clients;
397
 
            }
398
 
 
399
 
            break;
400
 
 
401
 
        case ButtonPress:
402
 
 
403
 
            if (event->xbutton.button != 1)
404
 
                break;
405
 
 
406
 
            it = mInputHandles.find (event->xbutton.window);
407
 
 
408
 
            if (it != mInputHandles.end ())
409
 
            {
410
 
                handle = it->second;
411
 
                if (handle)
412
 
                        handle->handleButtonPress ((XButtonEvent *) event);
413
 
            }
414
 
 
415
 
            break;
416
 
        case ConfigureNotify:
417
 
 
418
 
            w = screen->findTopLevelWindow (event->xconfigure.window);
419
 
 
420
 
            if (w)
421
 
                UnityMTGrabHandlesWindow::get (w)->relayout (w->inputRect (), true);
422
 
 
423
 
            break;
424
 
 
425
 
        case MapNotify:
426
 
 
427
 
            it = mInputHandles.find (event->xmap.window);
428
 
 
429
 
            if (it != mInputHandles.end ())
430
 
            {
431
 
              if (it->second)
432
 
                it->second->reposition (NULL, true);
433
 
            }
434
 
 
435
 
            break;
436
 
        default:
437
 
 
438
 
            break;
439
 
    }
440
 
 
441
 
    screen->handleEvent (event);
442
 
}
443
 
 
444
 
void
445
 
UnityMTGrabHandlesScreen::donePaint ()
446
 
{
447
 
    if (mMoreAnimate)
448
 
    {
449
 
        foreach (Unity::MT::GrabHandleGroup *handles, mGrabHandles)
450
 
        {
451
 
            if (handles->needsAnimate ())
452
 
            {
453
 
                foreach (Unity::MT::GrabHandle &handle, *handles)
454
 
                    cScreen->damageRegion ((CompRect &) handle);
455
 
            }
456
 
        }
457
 
    }
458
 
 
459
 
    cScreen->donePaint ();
460
 
}
461
 
 
462
 
void
463
 
UnityMTGrabHandlesScreen::preparePaint (int msec)
464
 
{
465
 
    if (mMoreAnimate)
466
 
    {
467
 
        mMoreAnimate = false;
468
 
 
469
 
        foreach (Unity::MT::GrabHandleGroup *handles, mGrabHandles)
470
 
        {
471
 
            mMoreAnimate |= handles->animate (msec);
472
 
        }
473
 
    }
474
 
 
475
 
    cScreen->preparePaint (msec);
 
391
          }
 
392
        }
 
393
 
 
394
        foreach(CompWindow * w, invalidated)
 
395
        UnityMTGrabHandlesWindow::get(w)->restackHandles();
 
396
 
 
397
        mLastClientListStacking = clients;
 
398
      }
 
399
 
 
400
      break;
 
401
 
 
402
    case ButtonPress:
 
403
 
 
404
      if (event->xbutton.button != 1)
 
405
        break;
 
406
 
 
407
      it = mInputHandles.find(event->xbutton.window);
 
408
 
 
409
      if (it != mInputHandles.end())
 
410
      {
 
411
        handle = it->second;
 
412
        if (handle)
 
413
          handle->handleButtonPress((XButtonEvent*) event);
 
414
      }
 
415
 
 
416
      break;
 
417
    case ConfigureNotify:
 
418
 
 
419
      w = screen->findTopLevelWindow(event->xconfigure.window);
 
420
 
 
421
      if (w)
 
422
        UnityMTGrabHandlesWindow::get(w)->relayout(w->inputRect(), true);
 
423
 
 
424
      break;
 
425
 
 
426
    case MapNotify:
 
427
 
 
428
      it = mInputHandles.find(event->xmap.window);
 
429
 
 
430
      if (it != mInputHandles.end())
 
431
      {
 
432
        if (it->second)
 
433
          it->second->reposition(NULL, true);
 
434
      }
 
435
 
 
436
      break;
 
437
    default:
 
438
 
 
439
      break;
 
440
  }
 
441
 
 
442
  screen->handleEvent(event);
 
443
}
 
444
 
 
445
void
 
446
UnityMTGrabHandlesScreen::donePaint()
 
447
{
 
448
  if (mMoreAnimate)
 
449
  {
 
450
    foreach(Unity::MT::GrabHandleGroup * handles, mGrabHandles)
 
451
    {
 
452
      if (handles->needsAnimate())
 
453
      {
 
454
        foreach(Unity::MT::GrabHandle & handle, *handles)
 
455
        cScreen->damageRegion((CompRect&) handle);
 
456
      }
 
457
    }
 
458
  }
 
459
 
 
460
  cScreen->donePaint();
 
461
}
 
462
 
 
463
void
 
464
UnityMTGrabHandlesScreen::preparePaint(int msec)
 
465
{
 
466
  if (mMoreAnimate)
 
467
  {
 
468
    mMoreAnimate = false;
 
469
 
 
470
    foreach(Unity::MT::GrabHandleGroup * handles, mGrabHandles)
 
471
    {
 
472
      mMoreAnimate |= handles->animate(msec);
 
473
    }
 
474
  }
 
475
 
 
476
  cScreen->preparePaint(msec);
476
477
}
477
478
 
478
479
bool
479
 
UnityMTGrabHandlesWindow::handleTimerActive ()
 
480
UnityMTGrabHandlesWindow::handleTimerActive()
480
481
{
481
482
  return _timer_handle != 0;
482
483
}
483
484
 
484
485
bool
485
 
UnityMTGrabHandlesWindow::allowHandles ()
 
486
UnityMTGrabHandlesWindow::allowHandles()
486
487
{
487
 
    /* Not on windows we can't move or resize */
488
 
    if (!(window->actions () & CompWindowActionResizeMask))
489
 
        return false;
490
 
 
491
 
    if (!(window->actions () & CompWindowActionMoveMask))
492
 
        return false;
493
 
 
494
 
    /* Not on override redirect windows */
495
 
    if (window->overrideRedirect ())
496
 
        return false;
497
 
 
498
 
    return true;
 
488
  /* Not on windows we can't move or resize */
 
489
  if (!(window->actions() & CompWindowActionResizeMask))
 
490
    return false;
 
491
 
 
492
  if (!(window->actions() & CompWindowActionMoveMask))
 
493
    return false;
 
494
 
 
495
  /* Not on override redirect windows */
 
496
  if (window->overrideRedirect())
 
497
    return false;
 
498
 
 
499
  return true;
499
500
}
500
501
 
501
502
void
502
 
UnityMTGrabHandlesWindow::getOutputExtents (CompWindowExtents &output)
 
503
UnityMTGrabHandlesWindow::getOutputExtents(CompWindowExtents& output)
503
504
{
504
 
    if (mHandles)
505
 
    {
506
 
        /* Only care about the handle on the outside */
507
 
        output.left   = MAX (output.left,   window->borderRect ().left   () + mHandles->at (0).width  () / 2);
508
 
        output.right  = MAX (output.right,  window->borderRect ().right  () + mHandles->at (0).width  () / 2);
509
 
        output.top    = MAX (output.top,    window->borderRect ().top    () + mHandles->at (0).height () / 2);
510
 
        output.bottom = MAX (output.bottom, window->borderRect ().bottom () + mHandles->at (0).height () / 2);
511
 
    }
512
 
    else
513
 
        window->getOutputExtents (output);
 
505
  if (mHandles)
 
506
  {
 
507
    /* Only care about the handle on the outside */
 
508
    output.left   = MAX(output.left,   window->borderRect().left() + mHandles->at(0).width() / 2);
 
509
    output.right  = MAX(output.right,  window->borderRect().right() + mHandles->at(0).width() / 2);
 
510
    output.top    = MAX(output.top,    window->borderRect().top() + mHandles->at(0).height() / 2);
 
511
    output.bottom = MAX(output.bottom, window->borderRect().bottom() + mHandles->at(0).height() / 2);
 
512
  }
 
513
  else
 
514
    window->getOutputExtents(output);
514
515
 
515
516
}
516
517
 
517
518
bool
518
 
UnityMTGrabHandlesWindow::glDraw (const GLMatrix            &transform,
519
 
                                  GLFragment::Attrib        &fragment,
520
 
                                  const CompRegion          &region,
521
 
                                  unsigned int              mask)
 
519
UnityMTGrabHandlesWindow::glDraw(const GLMatrix&            transform,
 
520
                                 GLFragment::Attrib&      fragment,
 
521
                                 const CompRegion&          region,
 
522
                                 unsigned int              mask)
522
523
{
523
 
    /* Draw the window on the bottom, we will be drawing the
524
 
     * handles on top */
525
 
    bool status = gWindow->glDraw (transform, fragment, region, mask);
526
 
 
527
 
    UMTGH_SCREEN (screen);
528
 
 
529
 
    if (mHandles && mHandles->visible ())
 
524
  /* Draw the window on the bottom, we will be drawing the
 
525
   * handles on top */
 
526
  bool status = gWindow->glDraw(transform, fragment, region, mask);
 
527
 
 
528
  UMTGH_SCREEN(screen);
 
529
 
 
530
  if (mHandles && mHandles->visible())
 
531
  {
 
532
    unsigned int handle = 0;
 
533
 
 
534
    foreach(Unity::MT::TextureLayout layout, mHandles->layout())
530
535
    {
531
 
        unsigned int handle = 0;
532
 
 
533
 
        foreach (Unity::MT::TextureLayout layout, mHandles->layout ())
534
 
        {
535
 
            /* We want to set the geometry of the dim to the window
536
 
             * region */
537
 
            CompRegion reg = CompRegion (*layout.second);
538
 
 
539
 
            struct _skipInfo
540
 
            {
541
 
                unsigned int vstate;
542
 
                unsigned int hstate;
543
 
                unsigned int handles[9];
544
 
            };
545
 
 
546
 
            const struct _skipInfo skip[3] = {
547
 
                {CompWindowStateMaximizedVertMask,
548
 
                 CompWindowStateMaximizedVertMask,
549
 
                 { 1, 1, 1, 0, 1, 1, 1, 0, 0 }},
550
 
                {CompWindowStateMaximizedHorzMask,
551
 
                 CompWindowStateMaximizedHorzMask,
552
 
                 {1, 0, 1, 1, 1, 0, 1, 1, 0 }},
553
 
                {CompWindowStateMaximizedVertMask,
554
 
                 CompWindowStateMaximizedHorzMask,
555
 
                 {1, 1, 1, 1, 1, 1, 1, 1, 1 }}};
556
 
 
557
 
            foreach (GLTexture *tex, *layout.first)
 
536
      /* We want to set the geometry of the dim to the window
 
537
       * region */
 
538
      CompRegion reg = CompRegion(*layout.second);
 
539
 
 
540
      struct _skipInfo
 
541
      {
 
542
        unsigned int vstate;
 
543
        unsigned int hstate;
 
544
        unsigned int handles[9];
 
545
      };
 
546
 
 
547
      const struct _skipInfo skip[3] =
 
548
      {
 
549
        {
 
550
          CompWindowStateMaximizedVertMask,
 
551
          CompWindowStateMaximizedVertMask,
 
552
          { 1, 1, 1, 0, 1, 1, 1, 0, 0 }
 
553
        },
 
554
        {
 
555
          CompWindowStateMaximizedHorzMask,
 
556
          CompWindowStateMaximizedHorzMask,
 
557
          {1, 0, 1, 1, 1, 0, 1, 1, 0 }
 
558
        },
 
559
        {
 
560
          CompWindowStateMaximizedVertMask,
 
561
          CompWindowStateMaximizedHorzMask,
 
562
          {1, 1, 1, 1, 1, 1, 1, 1, 1 }
 
563
        }
 
564
      };
 
565
 
 
566
      foreach(GLTexture * tex, *layout.first)
 
567
      {
 
568
        GLTexture::MatrixList matl;
 
569
        GLTexture::Matrix     mat = tex->matrix();
 
570
        CompRegion        paintRegion(region);
 
571
        bool          skipHandle = false;
 
572
 
 
573
        for (unsigned int j = 0; j < 3; j++)
 
574
        {
 
575
          if (skip[j].vstate & window->state() &&
 
576
              skip[j].hstate & window->state())
 
577
          {
 
578
            if (skip[j].handles[handle])
558
579
            {
559
 
                GLTexture::MatrixList matl;
560
 
                GLTexture::Matrix     mat = tex->matrix ();
561
 
                CompRegion            paintRegion (region);
562
 
                bool                  skipHandle = false;
563
 
 
564
 
                for (unsigned int j = 0; j < 3; j++)
565
 
                {
566
 
                    if (skip[j].vstate & window->state () &&
567
 
                        skip[j].hstate & window->state ())
568
 
                    {
569
 
                        if (skip[j].handles[handle])
570
 
                        {
571
 
                            skipHandle = true;
572
 
                            break;
573
 
                        }
574
 
                    }
575
 
                }
576
 
 
577
 
                if (skipHandle)
578
 
                    break;
579
 
 
580
 
                /* We can reset the window geometry since it will be
581
 
                 * re-added later */
582
 
                gWindow->geometry ().reset ();
583
 
 
584
 
                /* Scale the handles */
585
 
                mat.xx *= 1;
586
 
                mat.yy *= 1;
587
 
 
588
 
                /* Not sure what this does, but it is necessary
589
 
                 * (adjusts for scale?) */
590
 
                mat.x0 -= mat.xx * reg.boundingRect ().x1 ();
591
 
                mat.y0 -= mat.yy * reg.boundingRect ().y1 ();
592
 
 
593
 
                matl.push_back (mat);
594
 
 
595
 
                if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
596
 
                    paintRegion = infiniteRegion;
597
 
 
598
 
                /* Now allow plugins to mess with the geometry of our
599
 
                 * dim (so we get a nice render for things like
600
 
                 * wobbly etc etc */
601
 
                gWindow->glAddGeometry (matl, reg, paintRegion);
602
 
 
603
 
                /* Did it succeed? */
604
 
                if (gWindow->geometry ().vertices)
605
 
                {
606
 
                    fragment.setOpacity (mHandles->opacity ());
607
 
                    /* Texture rendering set-up */
608
 
                    us->gScreen->setTexEnvMode (GL_MODULATE);
609
 
                    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
610
 
                    /* Draw the dim texture with all of it's modified
611
 
                     * geometry glory */
612
 
                    gWindow->glDrawTexture (tex, fragment, mask | PAINT_WINDOW_BLEND_MASK
613
 
                                            | PAINT_WINDOW_TRANSLUCENT_MASK |
614
 
                                              PAINT_WINDOW_TRANSFORMED_MASK);
615
 
                    /* Texture rendering tear-down */
616
 
                    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
617
 
                    us->gScreen->setTexEnvMode (GL_REPLACE);
618
 
                }
 
580
              skipHandle = true;
 
581
              break;
619
582
            }
620
 
 
621
 
            handle++;
622
 
        }
 
583
          }
 
584
        }
 
585
 
 
586
        if (skipHandle)
 
587
          break;
 
588
 
 
589
        /* We can reset the window geometry since it will be
 
590
         * re-added later */
 
591
        gWindow->geometry().reset();
 
592
 
 
593
        /* Scale the handles */
 
594
        mat.xx *= 1;
 
595
        mat.yy *= 1;
 
596
 
 
597
        /* Not sure what this does, but it is necessary
 
598
         * (adjusts for scale?) */
 
599
        mat.x0 -= mat.xx * reg.boundingRect().x1();
 
600
        mat.y0 -= mat.yy * reg.boundingRect().y1();
 
601
 
 
602
        matl.push_back(mat);
 
603
 
 
604
        if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
 
605
          paintRegion = infiniteRegion;
 
606
 
 
607
        /* Now allow plugins to mess with the geometry of our
 
608
         * dim (so we get a nice render for things like
 
609
         * wobbly etc etc */
 
610
        gWindow->glAddGeometry(matl, reg, paintRegion);
 
611
 
 
612
        /* Did it succeed? */
 
613
        if (gWindow->geometry().vertices)
 
614
        {
 
615
          fragment.setOpacity(mHandles->opacity());
 
616
          /* Texture rendering set-up */
 
617
          us->gScreen->setTexEnvMode(GL_MODULATE);
 
618
          glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
619
          /* Draw the dim texture with all of it's modified
 
620
           * geometry glory */
 
621
          gWindow->glDrawTexture(tex, fragment, mask | PAINT_WINDOW_BLEND_MASK
 
622
                                 | PAINT_WINDOW_TRANSLUCENT_MASK |
 
623
                                 PAINT_WINDOW_TRANSFORMED_MASK);
 
624
          /* Texture rendering tear-down */
 
625
          glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
626
          us->gScreen->setTexEnvMode(GL_REPLACE);
 
627
        }
 
628
      }
 
629
 
 
630
      handle++;
623
631
    }
624
 
 
625
 
    return status;
626
 
}
627
 
 
628
 
void
629
 
UnityMTGrabHandlesWindow::relayout (const CompRect &r, bool hard)
630
 
{
631
 
    if (mHandles)
632
 
        mHandles->relayout (r, hard);
633
 
}
634
 
 
635
 
void
636
 
UnityMTGrabHandlesWindow::grabNotify (int x, int y, unsigned int state, unsigned int mask)
637
 
{
638
 
    window->grabNotify (x, y, state, mask);
639
 
}
640
 
 
641
 
void
642
 
UnityMTGrabHandlesWindow::moveNotify (int dx, int dy, bool immediate)
643
 
{
644
 
    if (mHandles)
645
 
        mHandles->relayout ((const CompRect &) window->inputRect (), false);
646
 
 
647
 
    window->moveNotify (dx, dy, immediate);
648
 
}
649
 
 
650
 
void
651
 
UnityMTGrabHandlesWindow::ungrabNotify ()
652
 
{
653
 
    window->ungrabNotify ();
 
632
  }
 
633
 
 
634
  return status;
 
635
}
 
636
 
 
637
void
 
638
UnityMTGrabHandlesWindow::relayout(const CompRect& r, bool hard)
 
639
{
 
640
  if (mHandles)
 
641
    mHandles->relayout(r, hard);
 
642
}
 
643
 
 
644
void
 
645
UnityMTGrabHandlesWindow::grabNotify(int x, int y, unsigned int state, unsigned int mask)
 
646
{
 
647
  window->grabNotify(x, y, state, mask);
 
648
}
 
649
 
 
650
void
 
651
UnityMTGrabHandlesWindow::moveNotify(int dx, int dy, bool immediate)
 
652
{
 
653
  if (mHandles)
 
654
    mHandles->relayout((const CompRect&) window->inputRect(), false);
 
655
 
 
656
  window->moveNotify(dx, dy, immediate);
 
657
}
 
658
 
 
659
void
 
660
UnityMTGrabHandlesWindow::ungrabNotify()
 
661
{
 
662
  window->ungrabNotify();
654
663
}
655
664
 
656
665
bool
657
 
UnityMTGrabHandlesWindow::handlesVisible ()
 
666
UnityMTGrabHandlesWindow::handlesVisible()
658
667
{
659
 
    if (!mHandles)
660
 
        return false;
661
 
    
662
 
    return mHandles->visible ();
 
668
  if (!mHandles)
 
669
    return false;
 
670
 
 
671
  return mHandles->visible();
663
672
}
664
673
 
665
674
void
666
 
UnityMTGrabHandlesWindow::hideHandles ()
 
675
UnityMTGrabHandlesWindow::hideHandles()
667
676
{
668
 
    if (mHandles)
669
 
        mHandles->hide ();
670
 
 
671
 
    window->updateWindowOutputExtents ();
672
 
    cWindow->damageOutputExtents ();
673
 
    
674
 
    disableTimer ();
 
677
  if (mHandles)
 
678
    mHandles->hide();
 
679
 
 
680
  window->updateWindowOutputExtents();
 
681
  cWindow->damageOutputExtents();
 
682
 
 
683
  disableTimer();
675
684
}
676
685
 
677
686
gboolean
678
 
UnityMTGrabHandlesWindow::onHideTimeout (gpointer data)
679
 
{
680
 
    UnityMTGrabHandlesWindow *self = static_cast<UnityMTGrabHandlesWindow*> (data);
681
 
    
682
 
    if (screen->grabbed ())
683
 
        return true;
684
 
 
685
 
    // hack
686
 
    self->hideHandles ();
687
 
    self->_mt_screen->mMoreAnimate = true;
688
 
    self->_timer_handle = 0;
689
 
    return false;
690
 
}
691
 
 
692
 
void
693
 
UnityMTGrabHandlesWindow::resetTimer ()
694
 
{
695
 
    if (_timer_handle)
696
 
        g_source_remove (_timer_handle);
697
 
    
698
 
    _timer_handle = g_timeout_add (2000, &UnityMTGrabHandlesWindow::onHideTimeout, this);
699
 
}
700
 
 
701
 
void
702
 
UnityMTGrabHandlesWindow::disableTimer ()
703
 
{
704
 
    if (_timer_handle)
705
 
        g_source_remove (_timer_handle);
706
 
}
707
 
 
708
 
void
709
 
UnityMTGrabHandlesWindow::showHandles (bool use_timer)
710
 
{    
711
 
    if (!mHandles)
712
 
    {
713
 
        mHandles = new Unity::MT::GrabHandleGroup (window->frame ());
714
 
        UnityMTGrabHandlesScreen::get (screen)->addHandles (mHandles);
715
 
    }
716
 
 
717
 
    if (!mHandles->visible ())
718
 
    {
719
 
        activate ();
720
 
        mHandles->show ();
721
 
        mHandles->relayout (window->inputRect (), true);
722
 
 
723
 
        window->updateWindowOutputExtents ();
724
 
        cWindow->damageOutputExtents ();
725
 
    }
726
 
    
727
 
    if (use_timer)
728
 
        resetTimer ();
 
687
UnityMTGrabHandlesWindow::onHideTimeout(gpointer data)
 
688
{
 
689
  UnityMTGrabHandlesWindow* self = static_cast<UnityMTGrabHandlesWindow*>(data);
 
690
 
 
691
  if (screen->grabbed())
 
692
    return true;
 
693
 
 
694
  // hack
 
695
  self->hideHandles();
 
696
  self->_mt_screen->mMoreAnimate = true;
 
697
  self->_timer_handle = 0;
 
698
  return false;
 
699
}
 
700
 
 
701
void
 
702
UnityMTGrabHandlesWindow::resetTimer()
 
703
{
 
704
  if (_timer_handle)
 
705
    g_source_remove(_timer_handle);
 
706
 
 
707
  _timer_handle = g_timeout_add(2000, &UnityMTGrabHandlesWindow::onHideTimeout, this);
 
708
}
 
709
 
 
710
void
 
711
UnityMTGrabHandlesWindow::disableTimer()
 
712
{
 
713
  if (_timer_handle)
 
714
    g_source_remove(_timer_handle);
 
715
}
 
716
 
 
717
void
 
718
UnityMTGrabHandlesWindow::showHandles(bool use_timer)
 
719
{
 
720
  if (!mHandles)
 
721
  {
 
722
    mHandles = new Unity::MT::GrabHandleGroup(window->frame());
 
723
    UnityMTGrabHandlesScreen::get(screen)->addHandles(mHandles);
 
724
  }
 
725
 
 
726
  if (!mHandles->visible())
 
727
  {
 
728
    activate();
 
729
    mHandles->show();
 
730
    mHandles->relayout(window->inputRect(), true);
 
731
 
 
732
    window->updateWindowOutputExtents();
 
733
    cWindow->damageOutputExtents();
 
734
  }
 
735
 
 
736
  if (use_timer)
 
737
    resetTimer();
 
738
  else
 
739
    disableTimer();
 
740
}
 
741
 
 
742
void
 
743
UnityMTGrabHandlesWindow::restackHandles()
 
744
{
 
745
  if (!mHandles)
 
746
    return;
 
747
 
 
748
  foreach(Unity::MT::GrabHandle & handle, *mHandles)
 
749
  handle.reposition(NULL, true);
 
750
}
 
751
 
 
752
void
 
753
UnityMTGrabHandlesScreen::addHandleWindow(Unity::MT::GrabHandle* h, Window w)
 
754
{
 
755
  mInputHandles.insert(std::pair <Window, Unity::MT::GrabHandle*> (w, h));
 
756
}
 
757
 
 
758
void
 
759
UnityMTGrabHandlesScreen::removeHandleWindow(Window w)
 
760
{
 
761
  mInputHandles.erase(w);
 
762
}
 
763
 
 
764
void
 
765
UnityMTGrabHandlesScreen::addHandles(Unity::MT::GrabHandleGroup* handles)
 
766
{
 
767
  mGrabHandles.push_back(handles);
 
768
}
 
769
 
 
770
void
 
771
UnityMTGrabHandlesScreen::removeHandles(Unity::MT::GrabHandleGroup* handles)
 
772
{
 
773
  mGrabHandles.remove(handles);
 
774
 
 
775
  mMoreAnimate = true;
 
776
}
 
777
 
 
778
bool
 
779
UnityMTGrabHandlesScreen::toggleHandles(CompAction*         action,
 
780
                                        CompAction::State  state,
 
781
                                        CompOption::Vector& options)
 
782
{
 
783
  CompWindow* w = screen->findWindow(CompOption::getIntOptionNamed(options,
 
784
                                                                   "window",
 
785
                                                                   0));
 
786
  if (w)
 
787
  {
 
788
    UMTGH_WINDOW(w);
 
789
 
 
790
    if (!uw->allowHandles())
 
791
      return false;
 
792
 
 
793
    if (uw->handlesVisible())
 
794
      uw->hideHandles();
729
795
    else
730
 
        disableTimer ();
731
 
}
732
 
 
733
 
void
734
 
UnityMTGrabHandlesWindow::restackHandles ()
735
 
{
736
 
    if (!mHandles)
737
 
        return;
738
 
 
739
 
    foreach (Unity::MT::GrabHandle &handle, *mHandles)
740
 
        handle.reposition (NULL, true);
741
 
}
742
 
 
743
 
void
744
 
UnityMTGrabHandlesScreen::addHandleWindow (Unity::MT::GrabHandle *h, Window w)
745
 
{
746
 
    mInputHandles.insert (std::pair <Window, Unity::MT::GrabHandle *> (w, h));
747
 
}
748
 
 
749
 
void
750
 
UnityMTGrabHandlesScreen::removeHandleWindow (Window w)
751
 
{
752
 
    mInputHandles.erase (w);
753
 
}
754
 
 
755
 
void
756
 
UnityMTGrabHandlesScreen::addHandles (Unity::MT::GrabHandleGroup *handles)
757
 
{
758
 
    mGrabHandles.push_back (handles);
759
 
}
760
 
 
761
 
void
762
 
UnityMTGrabHandlesScreen::removeHandles (Unity::MT::GrabHandleGroup *handles)
763
 
{
764
 
    mGrabHandles.remove (handles);
 
796
      uw->showHandles(true);
765
797
 
766
798
    mMoreAnimate = true;
767
 
}
768
 
 
769
 
bool
770
 
UnityMTGrabHandlesScreen::toggleHandles (CompAction         *action,
771
 
                                       CompAction::State  state,
772
 
                                       CompOption::Vector &options)
773
 
{
774
 
    CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
775
 
                                                                       "window",
776
 
                                                                       0));
777
 
    if (w)
778
 
    {
779
 
        UMTGH_WINDOW (w);
780
 
 
781
 
        if (!uw->allowHandles ())
782
 
            return false;
783
 
        
784
 
        if (uw->handlesVisible ())
785
 
            uw->hideHandles ();
786
 
        else
787
 
            uw->showHandles (true);
788
 
 
789
 
        mMoreAnimate = true;
790
 
    }
791
 
 
792
 
    return true;
793
 
}
794
 
 
795
 
bool
796
 
UnityMTGrabHandlesScreen::showHandles (CompAction         *action,
797
 
                                       CompAction::State  state,
798
 
                                       CompOption::Vector &options)
799
 
{
800
 
    CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
801
 
                                                                       "window",
802
 
                                                                       0));
803
 
    
804
 
    bool use_timer = CompOption::getBoolOptionNamed (options, "use-timer", true);
805
 
    
806
 
    if (w)
807
 
    {
808
 
        UMTGH_WINDOW (w);
809
 
 
810
 
        if (!uw->allowHandles ())
811
 
            return false;
812
 
        
813
 
        uw->showHandles (use_timer);
814
 
 
815
 
        if (!uw->handlesVisible ())
816
 
            mMoreAnimate = true;
817
 
    }
818
 
 
819
 
    return true;
820
 
}
821
 
 
822
 
bool
823
 
UnityMTGrabHandlesScreen::hideHandles (CompAction         *action,
824
 
                                       CompAction::State  state,
825
 
                                       CompOption::Vector &options)
826
 
{
827
 
    CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
828
 
                                                                       "window",
829
 
                                                                       0));
830
 
    if (w)
831
 
    {
832
 
        UMTGH_WINDOW (w);
833
 
 
834
 
        if (!uw->allowHandles ())
835
 
            return false;
836
 
        
837
 
        if (uw->handlesVisible ())
838
 
        {
839
 
            uw->hideHandles ();
840
 
            mMoreAnimate = true;
841
 
        }
842
 
    }
843
 
 
844
 
    return true;
845
 
}
846
 
 
847
 
UnityMTGrabHandlesScreen::UnityMTGrabHandlesScreen (CompScreen *s) :
848
 
    PluginClassHandler <UnityMTGrabHandlesScreen, CompScreen> (s),
849
 
    cScreen (CompositeScreen::get (s)),
850
 
    gScreen (GLScreen::get (s)),
851
 
    mGrabHandles (0),
852
 
    mHandleTextures (0),
853
 
    mLastClientListStacking (screen->clientList (true)),
854
 
    mCompResizeWindowAtom (XInternAtom (screen->dpy (),
855
 
                                        "_COMPIZ_RESIZE_NOTIFY", 0)),
856
 
    mMoreAnimate (false)
857
 
{
858
 
    ScreenInterface::setHandler (s);
859
 
    CompositeScreenInterface::setHandler (cScreen);
860
 
    GLScreenInterface::setHandler (gScreen);
861
 
 
862
 
    mHandleTextures.resize (NUM_HANDLES);
863
 
 
864
 
    for (unsigned int i = 0; i < NUM_HANDLES; i++)
865
 
    {
866
 
        CompString fname = "handle-";
867
 
        CompString pname ("unitymtgrabhandles");
868
 
 
869
 
        fname = compPrintf ("%s%i.png", fname.c_str (), i);
870
 
        mHandleTextures.at (i).first =
871
 
                GLTexture::readImageToTexture (fname, pname,
872
 
                                               mHandleTextures.at (i).second);
873
 
    }
874
 
 
875
 
    optionSetToggleHandlesKeyInitiate (boost::bind (&UnityMTGrabHandlesScreen::toggleHandles, this, _1, _2, _3));
876
 
    optionSetShowHandlesKeyInitiate (boost::bind (&UnityMTGrabHandlesScreen::showHandles, this, _1, _2, _3));
877
 
    optionSetHideHandlesKeyInitiate (boost::bind (&UnityMTGrabHandlesScreen::hideHandles, this, _1, _2, _3));
878
 
}
879
 
 
880
 
UnityMTGrabHandlesScreen::~UnityMTGrabHandlesScreen ()
881
 
{
882
 
    while (mGrabHandles.size ())
883
 
    {
884
 
        Unity::MT::GrabHandleGroup *handles = mGrabHandles.back ();
885
 
        delete handles;
886
 
        mGrabHandles.pop_back ();
887
 
    }
888
 
 
889
 
    mHandleTextures.clear ();
890
 
}
891
 
 
892
 
UnityMTGrabHandlesWindow::UnityMTGrabHandlesWindow (CompWindow *w) :
893
 
    PluginClassHandler <UnityMTGrabHandlesWindow, CompWindow> (w),
894
 
    window (w),
895
 
    cWindow (CompositeWindow::get (w)),
896
 
    gWindow (GLWindow::get (w)),
897
 
    mHandles (NULL)
898
 
{
899
 
    WindowInterface::setHandler (window);
900
 
    CompositeWindowInterface::setHandler (cWindow);
901
 
    GLWindowInterface::setHandler (gWindow);
902
 
    
903
 
    // hack
904
 
    _mt_screen = UnityMTGrabHandlesScreen::get (screen);
905
 
    _timer_handle = 0;
906
 
}
907
 
 
908
 
UnityMTGrabHandlesWindow::~UnityMTGrabHandlesWindow ()
909
 
{
910
 
    if (_timer_handle)
911
 
        g_source_remove (_timer_handle);
912
 
 
913
 
    if (mHandles)
914
 
    {
915
 
        UnityMTGrabHandlesScreen::get (screen)->removeHandles (mHandles);
916
 
        delete mHandles;
917
 
 
918
 
        mHandles = NULL;
919
 
    }
920
 
}
921
 
 
922
 
bool
923
 
UnityMTGrabHandlesPluginVTable::init ()
924
 
{
925
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
926
 
        !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
927
 
        !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
928
 
        return false;
929
 
 
930
 
    return true;
 
799
  }
 
800
 
 
801
  return true;
 
802
}
 
803
 
 
804
bool
 
805
UnityMTGrabHandlesScreen::showHandles(CompAction*         action,
 
806
                                      CompAction::State  state,
 
807
                                      CompOption::Vector& options)
 
808
{
 
809
  CompWindow* w = screen->findWindow(CompOption::getIntOptionNamed(options,
 
810
                                                                   "window",
 
811
                                                                   0));
 
812
 
 
813
  bool use_timer = CompOption::getBoolOptionNamed(options, "use-timer", true);
 
814
 
 
815
  if (w)
 
816
  {
 
817
    UMTGH_WINDOW(w);
 
818
 
 
819
    if (!uw->allowHandles())
 
820
      return false;
 
821
 
 
822
    uw->showHandles(use_timer);
 
823
 
 
824
    if (!uw->handlesVisible())
 
825
      mMoreAnimate = true;
 
826
  }
 
827
 
 
828
  return true;
 
829
}
 
830
 
 
831
bool
 
832
UnityMTGrabHandlesScreen::hideHandles(CompAction*         action,
 
833
                                      CompAction::State  state,
 
834
                                      CompOption::Vector& options)
 
835
{
 
836
  CompWindow* w = screen->findWindow(CompOption::getIntOptionNamed(options,
 
837
                                                                   "window",
 
838
                                                                   0));
 
839
  if (w)
 
840
  {
 
841
    UMTGH_WINDOW(w);
 
842
 
 
843
    if (!uw->allowHandles())
 
844
      return false;
 
845
 
 
846
    if (uw->handlesVisible())
 
847
    {
 
848
      uw->hideHandles();
 
849
      mMoreAnimate = true;
 
850
    }
 
851
  }
 
852
 
 
853
  return true;
 
854
}
 
855
 
 
856
UnityMTGrabHandlesScreen::UnityMTGrabHandlesScreen(CompScreen* s) :
 
857
  PluginClassHandler <UnityMTGrabHandlesScreen, CompScreen> (s),
 
858
  cScreen(CompositeScreen::get(s)),
 
859
  gScreen(GLScreen::get(s)),
 
860
  mGrabHandles(0),
 
861
  mHandleTextures(0),
 
862
  mLastClientListStacking(screen->clientList(true)),
 
863
  mCompResizeWindowAtom(XInternAtom(screen->dpy(),
 
864
                                    "_COMPIZ_RESIZE_NOTIFY", 0)),
 
865
  mMoreAnimate(false)
 
866
{
 
867
  ScreenInterface::setHandler(s);
 
868
  CompositeScreenInterface::setHandler(cScreen);
 
869
  GLScreenInterface::setHandler(gScreen);
 
870
 
 
871
  mHandleTextures.resize(NUM_HANDLES);
 
872
 
 
873
  for (unsigned int i = 0; i < NUM_HANDLES; i++)
 
874
  {
 
875
    CompString fname = "handle-";
 
876
    CompString pname("unitymtgrabhandles");
 
877
 
 
878
    fname = compPrintf("%s%i.png", fname.c_str(), i);
 
879
    mHandleTextures.at(i).first =
 
880
      GLTexture::readImageToTexture(fname, pname,
 
881
                                    mHandleTextures.at(i).second);
 
882
  }
 
883
 
 
884
  optionSetToggleHandlesKeyInitiate(boost::bind(&UnityMTGrabHandlesScreen::toggleHandles, this, _1, _2, _3));
 
885
  optionSetShowHandlesKeyInitiate(boost::bind(&UnityMTGrabHandlesScreen::showHandles, this, _1, _2, _3));
 
886
  optionSetHideHandlesKeyInitiate(boost::bind(&UnityMTGrabHandlesScreen::hideHandles, this, _1, _2, _3));
 
887
}
 
888
 
 
889
UnityMTGrabHandlesScreen::~UnityMTGrabHandlesScreen()
 
890
{
 
891
  while (mGrabHandles.size())
 
892
  {
 
893
    Unity::MT::GrabHandleGroup* handles = mGrabHandles.back();
 
894
    delete handles;
 
895
    mGrabHandles.pop_back();
 
896
  }
 
897
 
 
898
  mHandleTextures.clear();
 
899
}
 
900
 
 
901
UnityMTGrabHandlesWindow::UnityMTGrabHandlesWindow(CompWindow* w) :
 
902
  PluginClassHandler <UnityMTGrabHandlesWindow, CompWindow> (w),
 
903
  window(w),
 
904
  cWindow(CompositeWindow::get(w)),
 
905
  gWindow(GLWindow::get(w)),
 
906
  mHandles(NULL)
 
907
{
 
908
  WindowInterface::setHandler(window);
 
909
  CompositeWindowInterface::setHandler(cWindow);
 
910
  GLWindowInterface::setHandler(gWindow);
 
911
 
 
912
  // hack
 
913
  _mt_screen = UnityMTGrabHandlesScreen::get(screen);
 
914
  _timer_handle = 0;
 
915
}
 
916
 
 
917
UnityMTGrabHandlesWindow::~UnityMTGrabHandlesWindow()
 
918
{
 
919
  if (_timer_handle)
 
920
    g_source_remove(_timer_handle);
 
921
 
 
922
  if (mHandles)
 
923
  {
 
924
    UnityMTGrabHandlesScreen::get(screen)->removeHandles(mHandles);
 
925
    delete mHandles;
 
926
 
 
927
    mHandles = NULL;
 
928
  }
 
929
}
 
930
 
 
931
bool
 
932
UnityMTGrabHandlesPluginVTable::init()
 
933
{
 
934
  if (!CompPlugin::checkPluginABI("core", CORE_ABIVERSION) ||
 
935
      !CompPlugin::checkPluginABI("composite", COMPIZ_COMPOSITE_ABI) ||
 
936
      !CompPlugin::checkPluginABI("opengl", COMPIZ_OPENGL_ABI))
 
937
    return false;
 
938
 
 
939
  return true;
931
940
}