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

« back to all changes in this revision

Viewing changes to .pc/debian-changes-4.14.2-0ubuntu2/plugins/unityshell/src/minimizedwindowhandler.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:
 
1
/*
 
2
 * Copyright (C) 2011 Canonical Ltd.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
17
 *
 
18
 * Authored By:
 
19
 * Sam Spilsbury <sam.spilsbury@canonical.com>
 
20
 */
 
21
 
 
22
#include "minimizedwindowhandler.h"
 
23
#include <cstring>
 
24
 
 
25
namespace compiz
 
26
{
 
27
class PrivateMinimizedWindowHandler
 
28
{
 
29
public:
 
30
 
 
31
  PrivateMinimizedWindowHandler () {};
 
32
 
 
33
  Display      *mDpy;
 
34
  unsigned int mXid;
 
35
 
 
36
  std::list <MinimizedWindowHandler::Ptr> mTransients;
 
37
 
 
38
  WindowInputRemover *mRemover;
 
39
};
 
40
}
 
41
 
 
42
bool
 
43
compiz::MinimizedWindowHandler::contains (boost::shared_ptr <MinimizedWindowHandler> mw)
 
44
{
 
45
  for (MinimizedWindowHandler::Ptr h : priv->mTransients)
 
46
  {
 
47
    if (h->priv->mXid == mw->priv->mXid)
 
48
      return true;
 
49
  }
 
50
 
 
51
  return false;
 
52
}
 
53
 
 
54
void
 
55
compiz::MinimizedWindowHandler::setVisibility (bool visible, Window shapeWin)
 
56
{
 
57
  if (!visible && !priv->mRemover)
 
58
  {
 
59
    priv->mRemover = new compiz::WindowInputRemover (priv->mDpy, shapeWin);
 
60
    if (!priv->mRemover)
 
61
            return;
 
62
 
 
63
    if (priv->mRemover->save ())
 
64
            priv->mRemover->remove ();
 
65
  }
 
66
  else if (visible && priv->mRemover)
 
67
  {
 
68
    priv->mRemover->restore ();
 
69
 
 
70
    delete priv->mRemover;
 
71
    priv->mRemover = NULL;
 
72
  }
 
73
}
 
74
 
 
75
std::vector<unsigned int>
 
76
compiz::MinimizedWindowHandler::getTransients ()
 
77
{
 
78
  std::vector<unsigned int> transients;
 
79
  compiz::X11TransientForReader *reader = new compiz::X11TransientForReader (priv->mDpy, priv->mXid);
 
80
 
 
81
  transients = reader->getTransients ();
 
82
 
 
83
  delete reader;
 
84
 
 
85
  return transients;
 
86
}
 
87
 
 
88
void
 
89
compiz::MinimizedWindowHandler::minimize ()
 
90
{
 
91
  Atom          wmState = XInternAtom (priv->mDpy, "WM_STATE", 0);
 
92
  Atom          netWmState = XInternAtom (priv->mDpy, "_NET_WM_STATE", 0);
 
93
  Atom          netWmStateHidden = XInternAtom (priv->mDpy, "_NET_WM_STATE_HIDDEN", 0);
 
94
  Atom          actualType;
 
95
  int           actualFormat;
 
96
  unsigned long nItems, nLeft;
 
97
  void          *prop;
 
98
  unsigned long data[2];
 
99
  Window        root = DefaultRootWindow (priv->mDpy), parent = priv->mXid, lastParent = priv->mXid;
 
100
  Window        *children;
 
101
  unsigned int  nchildren;
 
102
  compiz::MinimizedWindowHandler::Ptr holder = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, 0));
 
103
  auto          predicate_this = boost::bind (&compiz::MinimizedWindowHandler::contains, this, _1);
 
104
  auto          predicate_holder = !boost::bind (&compiz::MinimizedWindowHandler::contains, holder.get (), _1);
 
105
 
 
106
  std::vector<unsigned int> transients = getTransients ();
 
107
 
 
108
  for (unsigned int &w : transients)
 
109
  {
 
110
    compiz::MinimizedWindowHandler::Ptr p = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, w));
 
111
    holder->priv->mTransients.push_back (p);
 
112
  }
 
113
 
 
114
  priv->mTransients.remove_if (predicate_holder);
 
115
  holder->priv->mTransients.remove_if (predicate_this);
 
116
 
 
117
  for (MinimizedWindowHandler::Ptr &mw : holder->priv->mTransients)
 
118
    priv->mTransients.push_back (mw);
 
119
 
 
120
  for (MinimizedWindowHandler::Ptr &mw : priv->mTransients)
 
121
    mw->minimize ();
 
122
 
 
123
  do
 
124
  {
 
125
    if (XQueryTree (priv->mDpy, parent, &root, &parent, &children, &nchildren))
 
126
    {
 
127
      if (root != parent)
 
128
        lastParent = parent;
 
129
      XFree (children);
 
130
    }
 
131
    else
 
132
      root = parent;
 
133
  } while (root != parent);
 
134
 
 
135
  setVisibility (false, lastParent);
 
136
 
 
137
  /* Change the WM_STATE to IconicState */
 
138
  data[0] = IconicState;
 
139
  data[1] = None;
 
140
 
 
141
  XChangeProperty (priv->mDpy, priv->mXid, wmState, wmState,
 
142
                   32, PropModeReplace, (unsigned char *) data, 2);
 
143
 
 
144
  if (XGetWindowProperty (priv->mDpy, priv->mXid, netWmState, 0L, 512L, false, XA_ATOM, &actualType, &actualFormat,
 
145
                          &nItems, &nLeft, (unsigned char **) &prop) == Success)
 
146
  {
 
147
    if (actualType == XA_ATOM && actualFormat == 32 && nItems && !nLeft)
 
148
    {
 
149
      Atom *data = (Atom *) prop;
 
150
 
 
151
      /* Don't append _NET_WM_STATE_HIDDEN */
 
152
      while (nItems--)
 
153
        if (*data++ == netWmStateHidden)
 
154
          netWmStateHidden = 0;
 
155
    }
 
156
 
 
157
    if (prop)
 
158
      XFree (prop);
 
159
  }
 
160
 
 
161
  /* Add _NET_WM_STATE_HIDDEN */
 
162
  if (netWmStateHidden)
 
163
    XChangeProperty (priv->mDpy, priv->mXid, netWmState, XA_ATOM,
 
164
                     32, PropModeAppend, (const unsigned char *) &netWmStateHidden, 1);
 
165
}
 
166
 
 
167
void
 
168
compiz::MinimizedWindowHandler::unminimize ()
 
169
{
 
170
  Atom          wmState = XInternAtom (priv->mDpy, "WM_STATE", 0);
 
171
  Atom          netWmState = XInternAtom (priv->mDpy, "_NET_WM_STATE", 0);
 
172
  Atom          netWmStateHidden = XInternAtom (priv->mDpy, "_NET_WM_STATE_HIDDEN", 0);
 
173
  Atom          *nextState = NULL;
 
174
  unsigned int  nextStateSize = 0;
 
175
  Atom          actualType;
 
176
  int           actualFormat;
 
177
  unsigned long nItems, nLeft;
 
178
  void          *prop;
 
179
  unsigned long data[2];
 
180
  Window        root = DefaultRootWindow (priv->mDpy), parent = priv->mXid, lastParent = priv->mXid;
 
181
  Window        *children;
 
182
  unsigned int  nchildren;
 
183
  compiz::MinimizedWindowHandler::Ptr holder = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, 0));
 
184
  auto          predicate_this = boost::bind (&compiz::MinimizedWindowHandler::contains, this, _1);
 
185
  auto          predicate_holder = !boost::bind (&compiz::MinimizedWindowHandler::contains, holder.get (), _1);
 
186
 
 
187
  std::vector<unsigned int> transients = getTransients ();
 
188
 
 
189
  for (unsigned int &w : transients)
 
190
  {
 
191
    compiz::MinimizedWindowHandler::Ptr p = compiz::MinimizedWindowHandler::Ptr (new compiz::MinimizedWindowHandler (priv->mDpy, w));
 
192
    holder->priv->mTransients.push_back (p);
 
193
  }
 
194
 
 
195
  priv->mTransients.remove_if (predicate_holder);
 
196
  holder->priv->mTransients.remove_if (predicate_this);
 
197
 
 
198
  for (MinimizedWindowHandler::Ptr &mw : holder->priv->mTransients)
 
199
    priv->mTransients.push_back (mw);
 
200
 
 
201
  for (MinimizedWindowHandler::Ptr &mw : priv->mTransients)
 
202
    mw->unminimize ();
 
203
 
 
204
  do
 
205
  {
 
206
    if (XQueryTree (priv->mDpy, parent, &root, &parent, &children, &nchildren))
 
207
    {
 
208
      if (root != parent)
 
209
        lastParent = parent;
 
210
      XFree (children);
 
211
    }
 
212
    else
 
213
      root = parent;
 
214
  } while (root != parent);
 
215
 
 
216
  setVisibility (true, lastParent);
 
217
 
 
218
  data[0] = NormalState;
 
219
  data[1] = None;
 
220
 
 
221
  XChangeProperty (priv->mDpy, priv->mXid, wmState, wmState,
 
222
                   32, PropModeReplace, (unsigned char *) data, 2);
 
223
 
 
224
  if (XGetWindowProperty (priv->mDpy, priv->mXid, netWmState, 0L, 512L, false, XA_ATOM, &actualType, &actualFormat,
 
225
                          &nItems, &nLeft, (unsigned char **) &prop) == Success)
 
226
  {
 
227
    if (actualType == XA_ATOM && actualFormat == 32 && nItems && !nLeft)
 
228
    {
 
229
      Atom *data = (Atom *) prop;
 
230
      Atom *pbegin = NULL;
 
231
      int  count = 0;
 
232
 
 
233
      nextStateSize = nItems;
 
234
 
 
235
      pbegin = nextState = (Atom *) malloc (sizeof (Atom) * nextStateSize);
 
236
      pbegin = nextState = (Atom *) memcpy (nextState, data, sizeof (Atom) * nextStateSize);
 
237
 
 
238
      /* Remove _NET_WM_STATE_HIDDEN */
 
239
      while (nItems--)
 
240
      {
 
241
        if (*nextState++ == netWmStateHidden)
 
242
        {
 
243
          nextState = (Atom *) memmove (nextState - 1, nextState, nItems);
 
244
          pbegin = nextState - count;
 
245
 
 
246
          nextStateSize--;
 
247
          pbegin = (Atom *) realloc (pbegin, sizeof (Atom) * nextStateSize);
 
248
        }
 
249
 
 
250
        count++;
 
251
      }
 
252
 
 
253
      nextState = pbegin;
 
254
    }
 
255
 
 
256
    XFree (prop);
 
257
  }
 
258
 
 
259
  /* Write new _NET_WM_STATE */
 
260
  if (nextState)
 
261
    XChangeProperty (priv->mDpy, priv->mXid, netWmState, XA_ATOM,
 
262
                     32, PropModeReplace, (const unsigned char *) nextState, nextStateSize);
 
263
  else
 
264
    XDeleteProperty (priv->mDpy, priv->mXid, netWmState);
 
265
}
 
266
 
 
267
compiz::MinimizedWindowHandler::MinimizedWindowHandler (Display *dpy, unsigned int xid)
 
268
{
 
269
  priv = new PrivateMinimizedWindowHandler;
 
270
 
 
271
  priv->mDpy = dpy;
 
272
  priv->mXid = xid;
 
273
  priv->mRemover = NULL;
 
274
}
 
275
 
 
276
compiz::MinimizedWindowHandler::~MinimizedWindowHandler ()
 
277
{
 
278
  delete priv;
 
279
}