summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2010-07-15 11:19:54 +0300
committerKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2010-07-15 11:19:54 +0300
commita0419cc1fa70a36874f84e157cc4821e120e1c5f (patch)
tree0d4e384e678512a1a41c7e47fcba8cf26719fca5 /src
parent50a5d297b52e066faf9d56e894e0e4b1f2c9f3bc (diff)
Changes: Add support for _MEEGOTOUCH_DECORATOR_BUTTONS window property
- this property allows specifying the areas where home and close buttons are on the application window. When pressed, we act as if the real home or close button had been pressed.
Diffstat (limited to 'src')
-rw-r--r--src/mcompatoms_p.h1
-rw-r--r--src/mcompositemanager.cpp21
-rw-r--r--src/mwindowpropertycache.cpp65
-rw-r--r--src/mwindowpropertycache.h8
4 files changed, 95 insertions, 0 deletions
diff --git a/src/mcompatoms_p.h b/src/mcompatoms_p.h
index dbd1979..312bdea 100644
--- a/src/mcompatoms_p.h
+++ b/src/mcompatoms_p.h
@@ -91,6 +91,7 @@ public:
_DUI_STATUSBAR_OVERLAY,
_MEEGOTOUCH_GLOBAL_ALPHA,
_MEEGO_STACKING_LAYER,
+ _MEEGOTOUCH_DECORATOR_BUTTONS,
#ifdef WINDOW_DEBUG
_M_WM_INFO,
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp
index 885d6e6..7c6a326 100644
--- a/src/mcompositemanager.cpp
+++ b/src/mcompositemanager.cpp
@@ -135,6 +135,7 @@ MCompAtoms::MCompAtoms()
"_DUI_STATUSBAR_OVERLAY",
"_MEEGOTOUCH_GLOBAL_ALPHA",
"_MEEGO_STACKING_LAYER",
+ "_MEEGOTOUCH_DECORATOR_BUTTONS",
#ifdef WINDOW_DEBUG
// custom properties for CITA
@@ -2292,6 +2293,7 @@ bool MCompositeManagerPrivate::x11EventFilter(XEvent *event)
damageEvent(e);
return true;
}
+ MCompositeWindow *cw;
switch (event->type) {
case DestroyNotify:
@@ -2312,6 +2314,25 @@ bool MCompositeManagerPrivate::x11EventFilter(XEvent *event)
clientMessageEvent(&event->xclient); break;
case ButtonRelease:
case ButtonPress:
+ cw = COMPOSITE_WINDOW(event->xbutton.window);
+ if (cw) {
+ int ev_x = event->xbutton.x;
+ int ev_y = event->xbutton.y;
+ QRect h = cw->propertyCache()->homeButtonGeometry();
+ if (h.x() <= ev_x && h.y() <= ev_y && h.y() + h.height() >= ev_y
+ && h.x() + h.width() >= ev_x)
+ exposeSwitcher();
+ QRect c = cw->propertyCache()->closeButtonGeometry();
+ if (c.x() <= ev_x && c.y() <= ev_y && c.y() + c.height() >= ev_y
+ && c.x() + c.width() >= ev_x) {
+ XClientMessageEvent ev;
+ memset(&ev, 0, sizeof(ev));
+ ev.type = ClientMessage;
+ ev.window = cw->window();
+ ev.message_type = ATOM(_NET_CLOSE_WINDOW);
+ rootMessageEvent(&ev);
+ }
+ }
XAllowEvents(QX11Info::display(), ReplayPointer, event->xbutton.time);
activateWindow(event->xbutton.window, event->xbutton.time);
// Qt needs to handle this event for the window frame buttons
diff --git a/src/mwindowpropertycache.cpp b/src/mwindowpropertycache.cpp
index 1ddc76f..976e11b 100644
--- a/src/mwindowpropertycache.cpp
+++ b/src/mwindowpropertycache.cpp
@@ -35,6 +35,7 @@ MWindowPropertyCache::MWindowPropertyCache(Window w,
: transient_for((Window)-1),
wm_protocols_valid(false),
icon_geometry_valid(false),
+ decor_buttons_valid(false),
has_alpha(-1),
global_alpha(-1),
is_decorator(-1),
@@ -48,6 +49,8 @@ MWindowPropertyCache::MWindowPropertyCache(Window w,
xcb_real_geom(0)
{
memset(&req_geom, 0, sizeof(req_geom));
+ memset(&home_button_geom, 0, sizeof(home_button_geom));
+ memset(&close_button_geom, 0, sizeof(close_button_geom));
if (!wa) {
attrs = xcb_get_window_attributes_reply(xcb_conn,
@@ -81,6 +84,9 @@ MWindowPropertyCache::MWindowPropertyCache(Window w,
ATOM(_NET_WM_WINDOW_TYPE),
XCB_ATOM_ATOM, 0, MAX_TYPES);
xcb_pict_formats_cookie = xcb_render_query_pict_formats(xcb_conn);
+ xcb_decor_buttons_cookie = xcb_get_property(xcb_conn, 0, window,
+ ATOM(_MEEGOTOUCH_DECORATOR_BUTTONS),
+ XCB_ATOM_CARDINAL, 0, 8);
}
MWindowPropertyCache::~MWindowPropertyCache()
@@ -123,6 +129,10 @@ MWindowPropertyCache::~MWindowPropertyCache()
xcb_pict_formats_cookie, 0);
if (pfr) free(pfr);
}
+ if (!decor_buttons_valid) {
+ r = xcb_get_property_reply(xcb_conn, xcb_decor_buttons_cookie, 0);
+ if (r) free(r);
+ }
}
bool MWindowPropertyCache::hasAlpha()
@@ -277,6 +287,14 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e)
icon_geometry_valid = false;
} else if (e->atom == ATOM(_MEEGOTOUCH_GLOBAL_ALPHA)) {
global_alpha = -1;
+ } else if (e->atom == ATOM(_MEEGOTOUCH_DECORATOR_BUTTONS)) {
+ if (!decor_buttons_valid)
+ // collect the old reply
+ buttonGeometryHelper();
+ decor_buttons_valid = false;
+ xcb_decor_buttons_cookie = xcb_get_property(xcb_conn, 0, window,
+ ATOM(_MEEGOTOUCH_DECORATOR_BUTTONS),
+ XCB_ATOM_CARDINAL, 0, 8);
} else if (e->atom == ATOM(WM_PROTOCOLS)) {
wm_protocols_valid = false;
} else if (e->atom == ATOM(WM_STATE)) {
@@ -307,6 +325,53 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e)
return false;
}
+void MWindowPropertyCache::buttonGeometryHelper()
+{
+ xcb_get_property_reply_t *r;
+ r = xcb_get_property_reply(xcb_conn, xcb_decor_buttons_cookie, 0);
+ if (!r) {
+ decor_buttons_valid = true;
+ return;
+ }
+ int len = xcb_get_property_value_length(r);
+ unsigned long x, y, w, h;
+ if (len == 0)
+ goto go_out;
+ else if (len != 8 * sizeof(unsigned long)) {
+ qWarning("%s: _MEEGOTOUCH_DECORATOR_BUTTONS size is %d", __func__, len);
+ goto go_out;
+ }
+ x = ((unsigned long*)xcb_get_property_value(r))[0];
+ y = ((unsigned long*)xcb_get_property_value(r))[1];
+ w = ((unsigned long*)xcb_get_property_value(r))[2];
+ h = ((unsigned long*)xcb_get_property_value(r))[3];
+ home_button_geom.setRect(x, y, w, h);
+ x = ((unsigned long*)xcb_get_property_value(r))[4];
+ y = ((unsigned long*)xcb_get_property_value(r))[5];
+ w = ((unsigned long*)xcb_get_property_value(r))[6];
+ h = ((unsigned long*)xcb_get_property_value(r))[7];
+ close_button_geom.setRect(x, y, w, h);
+go_out:
+ free(r);
+ decor_buttons_valid = true;
+}
+
+const QRect &MWindowPropertyCache::homeButtonGeometry()
+{
+ if (decor_buttons_valid)
+ return home_button_geom;
+ buttonGeometryHelper();
+ return home_button_geom;
+}
+
+const QRect &MWindowPropertyCache::closeButtonGeometry()
+{
+ if (decor_buttons_valid)
+ return close_button_geom;
+ buttonGeometryHelper();
+ return close_button_geom;
+}
+
const QList<Atom>& MWindowPropertyCache::supportedProtocols()
{
if (!wm_protocols_valid) {
diff --git a/src/mwindowpropertycache.h b/src/mwindowpropertycache.h
index c3c00c5..4d060ac 100644
--- a/src/mwindowpropertycache.h
+++ b/src/mwindowpropertycache.h
@@ -133,6 +133,9 @@ public:
const QRectF &iconGeometry();
+ const QRect &homeButtonGeometry();
+ const QRect &closeButtonGeometry();
+
/*!
* Returns value of _MEEGO_STACKING_LAYER. The value is between [0, 6].
*/
@@ -156,17 +159,21 @@ public:
}
private:
+ void buttonGeometryHelper();
+
Atom window_type_atom;
Window transient_for;
QList<Atom> wm_protocols;
bool wm_protocols_valid;
bool icon_geometry_valid;
+ bool decor_buttons_valid;
QRectF icon_geometry;
int has_alpha;
int global_alpha;
int is_decorator;
QList<Atom> net_wm_state;
QRect req_geom, real_geom;
+ QRect home_button_geom, close_button_geom;
XWMHints *wmhints;
xcb_get_window_attributes_reply_t *attrs;
int meego_layer, window_state;
@@ -179,6 +186,7 @@ private:
xcb_get_property_cookie_t xcb_meego_layer_cookie;
xcb_get_property_cookie_t xcb_is_decorator_cookie;
xcb_get_property_cookie_t xcb_window_type_cookie;
+ xcb_get_property_cookie_t xcb_decor_buttons_cookie;
xcb_render_query_pict_formats_cookie_t xcb_pict_formats_cookie;
static xcb_connection_t *xcb_conn;