diff options
author | Kimmo Hämäläinen <kimmo.hamalainen@nokia.com> | 2010-07-15 11:19:54 +0300 |
---|---|---|
committer | Kimmo Hämäläinen <kimmo.hamalainen@nokia.com> | 2010-07-15 11:19:54 +0300 |
commit | a0419cc1fa70a36874f84e157cc4821e120e1c5f (patch) | |
tree | 0d4e384e678512a1a41c7e47fcba8cf26719fca5 /src | |
parent | 50a5d297b52e066faf9d56e894e0e4b1f2c9f3bc (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.h | 1 | ||||
-rw-r--r-- | src/mcompositemanager.cpp | 21 | ||||
-rw-r--r-- | src/mwindowpropertycache.cpp | 65 | ||||
-rw-r--r-- | src/mwindowpropertycache.h | 8 |
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; |