~ubuntu-branches/ubuntu/oneiric/unity/oneiric

« back to all changes in this revision

Viewing changes to plugins/unityshell/src/inputremover.cpp

  • Committer: Package Import Robot
  • Author(s): Didier Roche
  • Date: 2011-09-12 08:12:54 UTC
  • Revision ID: package-import@ubuntu.com-20110912081254-qtz600pc32fva88o
Tags: 4.14.2-0ubuntu2
* Cherry-pick a fix for remapping minimized window correctly (LP: #840285)
* debian/control:
  - bump build-dep for latest compiz-dev ABI break

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
#include "inputremover.h"
 
23
#include <X11/Xregion.h>
23
24
#include <cstdio>
24
25
 
25
26
compiz::WindowInputRemover::WindowInputRemover (Display *dpy,
43
44
    restore ();
44
45
}
45
46
 
 
47
void
 
48
compiz::WindowInputRemover::sendShapeNotify ()
 
49
{
 
50
  /* Send a synthetic ShapeNotify event to the root window
 
51
   * since we ignored shape events when setting visibility
 
52
   * in order to avoid cycling in the shape handling code -
 
53
   * ignore the sent shape notify event since that will
 
54
   * be send_event = true */
 
55
 
 
56
  XShapeEvent  xsev;
 
57
  XEvent       *xev = (XEvent *) &xsev;
 
58
  Window       rootReturn, parentReturn;
 
59
  Window       childReturn;
 
60
  Window       *children;
 
61
  int          x, y, xOffset, yOffset;
 
62
  unsigned int width, height, depth, border, nchildren;
 
63
  int          shapeEvent, shapeError, shapeMask;
 
64
 
 
65
  /* FIXME: roundtrip */
 
66
  XShapeQueryExtension (mDpy, &shapeEvent, &shapeError);
 
67
  shapeMask = XShapeInputSelected (mDpy, mShapeWindow);
 
68
 
 
69
  xev->type   = shapeEvent + ShapeNotify;
 
70
  xsev.window = mShapeWindow;
 
71
 
 
72
  if (!mRemoved)
 
73
  {
 
74
    /* FIXME: these roundtrips suck */
 
75
    XGetGeometry (mDpy, mShapeWindow, &rootReturn, &x, &y, &width, &height, &depth, &border);
 
76
    XQueryTree (mDpy, mShapeWindow, &rootReturn, &parentReturn, &children, &nchildren);
 
77
 
 
78
    /* We need to translate the co-ordinates of the origin to the
 
79
     * client window to its parent to find out the offset of its
 
80
     * position so that we can subtract that from the final bounding
 
81
     * rect of the window shape according to the Shape extension
 
82
     * specification */
 
83
 
 
84
    XTranslateCoordinates (mDpy, mShapeWindow, parentReturn, 0, 0, &xOffset, &yOffset, &childReturn);
 
85
 
 
86
    xev->type = ShapeBounding;
 
87
 
 
88
    /* Calculate extents of the bounding shape */
 
89
    if (!mNBoundingRects)
 
90
    {
 
91
      /* No set input shape, we must use the client geometry */
 
92
      xsev.x = x - xOffset;
 
93
      xsev.y = y - yOffset;
 
94
      xsev.width = width; 
 
95
      xsev.height = height;
 
96
      xsev.shaped = false;
 
97
    }
 
98
    else
 
99
    {
 
100
      Region      boundingRegion = XCreateRegion ();
 
101
 
 
102
      for (int i = 0; i < mNBoundingRects; i++)
 
103
        XUnionRectWithRegion (&(mBoundingRects[i]), boundingRegion, boundingRegion);
 
104
 
 
105
      xsev.x = boundingRegion->extents.x1 - xOffset;
 
106
      xsev.y = boundingRegion->extents.y1 - yOffset;
 
107
      xsev.width = boundingRegion->extents.x2 - boundingRegion->extents.x1;
 
108
      xsev.height = boundingRegion->extents.y2 - boundingRegion->extents.y1;
 
109
      xsev.shaped = true;
 
110
 
 
111
      XDestroyRegion (boundingRegion);
 
112
    }
 
113
 
 
114
    xsev.time = CurrentTime;
 
115
    XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
 
116
 
 
117
    xev->type = ShapeInput;
 
118
 
 
119
    /* Calculate extents of the bounding shape */
 
120
    if (!mNInputRects)
 
121
    {
 
122
      /* No set input shape, we must use the client geometry */
 
123
      xsev.x = x - xOffset;
 
124
      xsev.y = y - yOffset;
 
125
      xsev.width = width; 
 
126
      xsev.height = height;
 
127
      xsev.shaped = false;
 
128
    }
 
129
    else
 
130
    {
 
131
      Region      inputRegion = XCreateRegion ();
 
132
 
 
133
      for (int i = 0; i < mNInputRects; i++)
 
134
        XUnionRectWithRegion (&(mInputRects[i]), inputRegion, inputRegion);
 
135
 
 
136
      xsev.x = inputRegion->extents.x1 - xOffset;
 
137
      xsev.y = inputRegion->extents.y1 - yOffset;
 
138
      xsev.width = inputRegion->extents.x2 - inputRegion->extents.x1;
 
139
      xsev.height = inputRegion->extents.y2 - inputRegion->extents.y1;
 
140
      xsev.shaped = true;
 
141
 
 
142
      XDestroyRegion (inputRegion);
 
143
    }
 
144
 
 
145
    xsev.time = CurrentTime;
 
146
    XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
 
147
 
 
148
    if (children)
 
149
      XFree (children);
 
150
  }
 
151
  else
 
152
  {
 
153
    xev->type = ShapeBounding;
 
154
 
 
155
    xsev.x = 0;
 
156
    xsev.y = 0;
 
157
    xsev.width = 0;
 
158
    xsev.height = 0;
 
159
    xsev.shaped = true;
 
160
 
 
161
    xsev.time = CurrentTime;
 
162
    XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
 
163
 
 
164
    xev->type = ShapeInput;
 
165
 
 
166
    /* Both ShapeBounding and ShapeInput are null */
 
167
 
 
168
    xsev.time = CurrentTime;
 
169
    XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
 
170
  }
 
171
}
 
172
 
46
173
bool
47
174
compiz::WindowInputRemover::save ()
48
175
{
111
238
 
112
239
  XShapeSelectInput (mDpy, mShapeWindow, ShapeNotify);
113
240
 
 
241
  sendShapeNotify ();
 
242
 
114
243
  mRemoved = true;
115
244
  return true;
116
245
}
125
254
      XShapeCombineRectangles (mDpy, mShapeWindow, ShapeInput, 0, 0,
126
255
                               mInputRects, mNInputRects,
127
256
                               ShapeSet, mInputRectOrdering);
 
257
 
128
258
    }
129
259
    else
130
260
    {
153
283
 
154
284
  XShapeSelectInput (mDpy, mShapeWindow, mShapeMask);
155
285
 
 
286
  sendShapeNotify ();
 
287
 
156
288
  mRemoved = false;
157
289
  mNInputRects  = 0;
158
290
  mInputRects = NULL;