| 61 |
@@ -61,7 +61,7 @@ |
| 61 |
//! @brief Frame constructor
|
| 62 |
Frame::Frame(Client *client, AutoProperty *ap)
|
| 63 |
: PDecor(WindowManager::instance()->getScreen()->getDpy(), WindowManager::instance()->getTheme(),
|
| 64 |
Frame::getClientDecorName(client)),
|
| 65 |
Frame::getClientDecorName(client), client->getWindow()),
|
| 66 |
_id(0), _client(0), _class_hint(0),
|
| 67 |
_non_fullscreen_decor_state(0), _non_fullscreen_layer(LAYER_NORMAL)
|
| 68 |
{
|
| ... |
|
| 1120 |
@@ -1120,6 +1120,7 @@ |
| 1120 |
}
|
| 1121 |
|
| 1122 |
setShaded(STATE_UNSET); // make sure the frame isn't shaded
|
| 1123 |
setStateFullscreen(STATE_UNSET);
|
| 1124 |
|
| 1125 |
// Initialize variables
|
| 1126 |
int start_x, new_x;
|
| ... |
|
| 1376 |
@@ -1375,6 +1376,7 @@ |
| 1376 |
}
|
| 1377 |
|
| 1378 |
setShaded(STATE_UNSET);
|
| 1379 |
setStateFullscreen(STATE_UNSET);
|
| 1380 |
|
| 1381 |
// make sure the two states are in sync if toggling
|
| 1382 |
if ((horz == vert) && (sa == STATE_TOGGLE)) {
|
| ... |
|
| 1465 |
@@ -1463,7 +1465,7 @@ |
| 1465 |
}
|
| 1466 |
|
| 1467 |
fixGeometry(); // harbour already considered
|
| 1466 |
downSize(true, true); // keep x and keep y ( make conform to inc size )
|
| 1469 |
downSize(_gm, true, true); // keep x and keep y ( make conform to inc size )
|
| 1470 |
|
| 1471 |
moveResize(_gm.x, _gm.y, _gm.width, _gm.height);
|
| 1472 |
|
| ... |
|
| 1754 |
@@ -1752,7 +1754,7 @@ |
| 1754 |
break;
|
| 1755 |
}
|
| 1756 |
|
| 1755 |
downSize((direction != DIRECTION_LEFT), (direction != DIRECTION_UP));
|
| 1758 |
downSize(_gm, (direction != DIRECTION_LEFT), (direction != DIRECTION_UP));
|
| 1759 |
|
| 1760 |
moveResize(_gm.x, _gm.y, _gm.width, _gm.height);
|
| 1761 |
}
|
| ... |
|
| 1929 |
@@ -1927,9 +1929,11 @@ |
| 1929 |
}
|
| 1930 |
}
|
| 1931 |
|
| 1930 |
//! @brief Makes Frame conform to Clients width and height inc
|
| 1933 |
/**
|
| 1934 |
* Makes gm conform to _clients width and height inc.
|
| 1935 |
*/
|
| 1936 |
void
|
| 1935 |
Frame::downSize(bool keep_x, bool keep_y)
|
| 1938 |
Frame::downSize(Geometry &gm, bool keep_x, bool keep_y)
|
| 1939 |
{
|
| 1940 |
XSizeHints *size_hint = _client->getXSizeHints(); // convenience
|
| 1941 |
|
| ... |
|
| 1944 |
@@ -1940,9 +1944,9 @@ |
| 1944 |
? size_hint->base_width
|
| 1945 |
: (size_hint->flags&PMinSize) ? size_hint->min_width : 0;
|
| 1946 |
|
| 1943 |
_gm.width -= (getChildWidth() - b_x) % size_hint->width_inc;
|
| 1948 |
gm.width -= (getChildWidth() - b_x) % size_hint->width_inc;
|
| 1949 |
if (! keep_x) {
|
| 1946 |
_gm.x = o_r - _gm.width;
|
| 1951 |
gm.x = o_r - gm.width;
|
| 1952 |
}
|
| 1953 |
}
|
| 1954 |
|
| ... |
|
| 1957 |
@@ -1953,9 +1957,9 @@ |
| 1957 |
? size_hint->base_height
|
| 1958 |
: (size_hint->flags&PMinSize) ? size_hint->min_height : 0;
|
| 1959 |
|
| 1956 |
_gm.height -= (getChildHeight() - b_y) % size_hint->height_inc;
|
| 1961 |
gm.height -= (getChildHeight() - b_y) % size_hint->height_inc;
|
| 1962 |
if (! keep_y) {
|
| 1959 |
_gm.y = o_b - _gm.height;
|
| 1964 |
gm.y = o_b - gm.height;
|
| 1965 |
}
|
| 1966 |
}
|
| 1967 |
}
|
| ... |
|
| 2021 |
@@ -2017,125 +2021,72 @@ |
| 2021 |
void
|
| 2022 |
Frame::handleConfigureRequestGeometry(XConfigureRequestEvent *ev, Client *client)
|
| 2023 |
{
|
| 2020 |
// Look for fullscreen requests
|
| 2021 |
const long all_geometry = CWX|CWY|CWWidth|CWHeight;
|
| 2022 |
bool is_fullscreen = false;
|
| 2023 |
if (Config::instance()->isFullscreenDetect()
|
| 2024 |
&& ! client->isCfgDeny(CFG_DENY_SIZE)
|
| 2025 |
&& ! client->isCfgDeny(CFG_DENY_POSITION)
|
| 2026 |
&& ((ev->value_mask&all_geometry) == static_cast<unsigned>(all_geometry))) {
|
| 2027 |
|
| 2028 |
Geometry gm_request(ev->x, ev->y, ev->width, ev->height);
|
| 2029 |
if (gm_request == _scr->getScreenGeometry()
|
| 2030 |
|| gm_request == _scr->getHeadGeometry(_scr->getNearestHead(ev->x, ev->y))) {
|
| 2031 |
|
| 2032 |
is_fullscreen = true;
|
| 2033 |
setStateFullscreen(STATE_SET);
|
| 2034 |
}
|
| 2039 |
if (isRequestGeometryFullscreen(ev, client)) {
|
| 2040 |
client->configureRequestSend();
|
| 2041 |
return;
|
| 2042 |
}
|
| 2043 |
|
| 2040 |
if (! is_fullscreen) {
|
| 2041 |
bool change_geometry = false;
|
| 2042 |
|
| 2043 |
if (! client->isCfgDeny(CFG_DENY_SIZE)
|
| 2044 |
&& (ev->value_mask & (CWWidth|CWHeight)) ) {
|
| 2045 |
|
| 2046 |
resizeChild(ev->width, ev->height);
|
| 2047 |
_client->setShaped(setShape());
|
| 2052 |
bool change_geometry = false;
|
| 2053 |
if (! client->isCfgDeny(CFG_DENY_SIZE)
|
| 2054 |
&& (ev->value_mask & (CWWidth|CWHeight))) {
|
| 2055 |
resizeChild(ev->width, ev->height);
|
| 2056 |
_client->setShaped(setShape());
|
| 2057 |
change_geometry = true;
|
| 2058 |
}
|
| 2059 |
|
| 2056 |
change_geometry = true;
|
| 2057 |
}
|
| 2062 |
if (! client->isCfgDeny(CFG_DENY_POSITION)
|
| 2063 |
&& (ev->value_mask & (CWX|CWY)) ) {
|
| 2064 |
calcGravityPosition(_client->getXSizeHints()->win_gravity,
|
| 2065 |
ev->x, ev->y, _gm.x, _gm.y);
|
| 2066 |
move(_gm.x, _gm.y);
|
| 2067 |
change_geometry = true;
|
| 2068 |
}
|
| 2069 |
|
| 2066 |
if (! client->isCfgDeny(CFG_DENY_POSITION)
|
| 2067 |
&& (ev->value_mask & (CWX|CWY)) ) {
|
| 2072 |
// Remove fullscreen state if client changes it size
|
| 2073 |
if (change_geometry && Config::instance()->isFullscreenDetect()) {
|
| 2074 |
setStateFullscreen(STATE_UNSET);
|
| 2075 |
}
|
| 2076 |
}
|
| 2077 |
|
| 2074 |
calcGravityPosition(_client->getXSizeHints()->win_gravity,
|
| 2075 |
ev->x, ev->y, _gm.x, _gm.y);
|
| 2076 |
move(_gm.x, _gm.y);
|
| 2081 |
/**
|
| 2082 |
* Check if requested size if "fullscreen"
|
| 2083 |
*/
|
| 2084 |
bool
|
| 2085 |
Frame::isRequestGeometryFullscreen(XConfigureRequestEvent *ev, Client *client)
|
| 2086 |
{
|
| 2087 |
bool is_fullscreen = false;
|
| 2088 |
if (! client->isCfgDeny(CFG_DENY_SIZE)
|
| 2089 |
&& ! client->isCfgDeny(CFG_DENY_POSITION)) {
|
| 2090 |
int nearest_head = _scr->getNearestHead(ev->x, ev->y);
|
| 2091 |
Geometry gm_request(ev->x, ev->y, ev->width, ev->height);
|
| 2092 |
Geometry gm_screen(_scr->getScreenGeometry());
|
| 2093 |
Geometry gm_head(_scr->getHeadGeometry(nearest_head));
|
| 2094 |
|
| 2091 |
change_geometry = true;
|
| 2096 |
if (gm_request == gm_screen || gm_request == gm_head) {
|
| 2097 |
is_fullscreen = true;
|
| 2098 |
} else {
|
| 2099 |
downSize(gm_screen, true, true);
|
| 2100 |
downSize(gm_head, true, true);
|
| 2101 |
if (gm_request == gm_screen || gm_request == gm_head) {
|
| 2102 |
is_fullscreen = true;
|
| 2103 |
}
|
| 2104 |
}
|
| 2105 |
|
| 2102 |
// Remove fullscreen state if client changes it size
|
| 2103 |
if (change_geometry && Config::instance()->isFullscreenDetect()) {
|
| 2104 |
setStateFullscreen(STATE_UNSET);
|
| 2109 |
if (is_fullscreen && Config::instance()->isFullscreenDetect()) {
|
| 2110 |
setStateFullscreen(STATE_SET);
|
| 2111 |
}
|
| 2112 |
}
|
| 2113 |
return is_fullscreen;
|
| 2114 |
}
|
| 2115 |
|
| 2112 |
//! @brief
|
| 2117 |
/**
|
| 2118 |
* Handle client message.
|
| 2119 |
*/
|
| 2120 |
void
|
| 2121 |
Frame::handleClientMessage(XClientMessageEvent *ev, Client *client)
|
| 2122 |
{
|
| 2119 |
StateAction sa;
|
| 2120 |
|
| 2125 |
if (ev->message_type == Atoms::getAtom(STATE)) {
|
| 2122 |
if (ev->data.l[0]== NET_WM_STATE_REMOVE) {
|
| 2123 |
sa = STATE_UNSET;
|
| 2124 |
} else if (ev->data.l[0]== NET_WM_STATE_ADD) {
|
| 2125 |
sa = STATE_SET;
|
| 2126 |
} else if (ev->data.l[0]== NET_WM_STATE_TOGGLE) {
|
| 2127 |
sa = STATE_TOGGLE;
|
| 2128 |
} else {
|
| 2129 |
#ifdef DEBUG
|
| 2130 |
cerr << __FILE__ << "@" << __LINE__ << ": "
|
| 2131 |
<< "None of StateAdd, StateRemove or StateToggle." << endl;
|
| 2132 |
#endif // DEBUG
|
| 2133 |
return;
|
| 2134 |
}
|
| 2135 |
|
| 2136 |
#define IS_STATE(S) ((ev->data.l[1] == long(Atoms::getAtom(S))) || (ev->data.l[2] == long(Atoms::getAtom(S))))
|
| 2137 |
|
| 2138 |
// actions that only is going to be applied on the active client
|
| 2139 |
if (client == _client) {
|
| 2140 |
// there is no modal support in pekwm yet
|
| 2141 |
// if (IS_STATE(STATE_MODAL)) {
|
| 2142 |
// is_modal=true;
|
| 2143 |
// }
|
| 2144 |
if (IS_STATE(STATE_STICKY)) {
|
| 2145 |
setStateSticky(sa);
|
| 2146 |
}
|
| 2147 |
if (IS_STATE(STATE_MAXIMIZED_HORZ)
|
| 2148 |
&& ! client->isCfgDeny(CFG_DENY_STATE_MAXIMIZED_HORZ)) {
|
| 2149 |
setStateMaximized(sa, true, false, false);
|
| 2150 |
}
|
| 2151 |
if (IS_STATE(STATE_MAXIMIZED_VERT)
|
| 2152 |
&& ! client->isCfgDeny(CFG_DENY_STATE_MAXIMIZED_VERT)) {
|
| 2153 |
setStateMaximized(sa, false, true, false);
|
| 2154 |
}
|
| 2155 |
if (IS_STATE(STATE_SHADED)) {
|
| 2156 |
setShaded(sa);
|
| 2157 |
}
|
| 2158 |
if (IS_STATE(STATE_HIDDEN)
|
| 2159 |
&& ! client->isCfgDeny(CFG_DENY_STATE_HIDDEN)) {
|
| 2160 |
setStateIconified(sa);
|
| 2161 |
}
|
| 2162 |
if (IS_STATE(STATE_FULLSCREEN)
|
| 2163 |
&& ! client->isCfgDeny(CFG_DENY_STATE_FULLSCREEN)) {
|
| 2164 |
setStateFullscreen(sa);
|
| 2165 |
}
|
| 2166 |
if (IS_STATE(STATE_ABOVE)
|
| 2167 |
&& ! client->isCfgDeny(CFG_DENY_STATE_ABOVE)) {
|
| 2168 |
setStateAlwaysOnTop(sa);
|
| 2169 |
}
|
| 2170 |
if (IS_STATE(STATE_BELOW)
|
| 2171 |
&& ! client->isCfgDeny(CFG_DENY_STATE_BELOW)) {
|
| 2172 |
setStateAlwaysBelow(sa);
|
| 2173 |
}
|
| 2174 |
}
|
| 2175 |
|
| 2176 |
if (IS_STATE(STATE_SKIP_TASKBAR)) {
|
| 2177 |
client->setStateSkip(sa, SKIP_TASKBAR);
|
| 2178 |
}
|
| 2179 |
if (IS_STATE(STATE_SKIP_PAGER)) {
|
| 2180 |
client->setStateSkip(sa, SKIP_PAGER);
|
| 2181 |
}
|
| 2182 |
if (IS_STATE(STATE_DEMANDS_ATTENTION)) {
|
| 2183 |
client->setStateDemandsAttention(sa, true);
|
| 2184 |
}
|
| 2185 |
|
| 2186 |
client->updateEwmhStates();
|
| 2187 |
|
| 2192 |
handleClientStateMessage(ev, client);
|
| 2193 |
} else if (ev->message_type == Atoms::getAtom(NET_ACTIVE_WINDOW)) {
|
| 2194 |
if (! client->isCfgDeny(CFG_DENY_ACTIVE_WINDOW)) {
|
| 2195 |
// Active child if it's not the active child
|
| ... |
|
| 2118 |
@@ -2167,9 +2118,107 @@ |
| 2118 |
iconify();
|
| 2119 |
}
|
| 2120 |
}
|
| 2170 |
#undef IS_STATE
|
| 2122 |
}
|
| 2123 |
|
| 2124 |
/**
|
| 2125 |
* Handle _NET_WM_STATE atom.
|
| 2126 |
*/
|
| 2127 |
void
|
| 2128 |
Frame::handleClientStateMessage(XClientMessageEvent *ev, Client *client)
|
| 2129 |
{
|
| 2130 |
StateAction sa = getStateActionFromMessage(ev);
|
| 2131 |
handleStateAtom(sa, ev->data.l[1], client);
|
| 2132 |
if (ev->data.l[2] != 0) {
|
| 2133 |
handleStateAtom(sa, ev->data.l[2], client);
|
| 2134 |
}
|
| 2135 |
client->updateEwmhStates();
|
| 2136 |
}
|
| 2137 |
|
| 2138 |
/**
|
| 2139 |
* Get StateAction from NET_WM atom.
|
| 2140 |
*/
|
| 2141 |
StateAction
|
| 2142 |
Frame::getStateActionFromMessage(XClientMessageEvent *ev)
|
| 2143 |
{
|
| 2144 |
StateAction sa = STATE_SET;
|
| 2145 |
if (ev->data.l[0]== NET_WM_STATE_REMOVE) {
|
| 2146 |
sa = STATE_UNSET;
|
| 2147 |
} else if (ev->data.l[0]== NET_WM_STATE_ADD) {
|
| 2148 |
sa = STATE_SET;
|
| 2149 |
} else if (ev->data.l[0]== NET_WM_STATE_TOGGLE) {
|
| 2150 |
sa = STATE_TOGGLE;
|
| 2151 |
}
|
| 2152 |
return sa;
|
| 2153 |
}
|
| 2154 |
|
| 2155 |
/**
|
| 2156 |
* Handle state atom for client.
|
| 2157 |
*/
|
| 2158 |
void
|
| 2159 |
Frame::handleStateAtom(StateAction sa, long atom, Client *client)
|
| 2160 |
{
|
| 2161 |
if (client == _client) {
|
| 2162 |
handleCurrentClientStateAtom(sa, atom, client);
|
| 2163 |
}
|
| 2164 |
|
| 2165 |
switch (atom) {
|
| 2166 |
case STATE_SKIP_TASKBAR:
|
| 2167 |
client->setStateSkip(sa, SKIP_TASKBAR);
|
| 2168 |
break;
|
| 2169 |
case STATE_SKIP_PAGER:
|
| 2170 |
client->setStateSkip(sa, SKIP_PAGER);
|
| 2171 |
break;
|
| 2172 |
case STATE_DEMANDS_ATTENTION:
|
| 2173 |
client->setStateDemandsAttention(sa, true);
|
| 2174 |
break;
|
| 2175 |
}
|
| 2176 |
}
|
| 2177 |
|
| 2178 |
/**
|
| 2179 |
* Handle state atom for actions that apply only on active client.
|
| 2180 |
*/
|
| 2181 |
void
|
| 2182 |
Frame::handleCurrentClientStateAtom(StateAction sa, long atom, Client *client)
|
| 2183 |
{
|
| 2184 |
switch (atom) {
|
| 2185 |
case STATE_STICKY:
|
| 2186 |
setStateSticky(sa);
|
| 2187 |
break;
|
| 2188 |
case STATE_MAXIMIZED_HORZ:
|
| 2189 |
if (! client->isCfgDeny(CFG_DENY_STATE_MAXIMIZED_HORZ)) {
|
| 2190 |
setStateMaximized(sa, true, false, false);
|
| 2191 |
}
|
| 2192 |
break;
|
| 2193 |
case STATE_MAXIMIZED_VERT:
|
| 2194 |
if (! client->isCfgDeny(CFG_DENY_STATE_MAXIMIZED_VERT)) {
|
| 2195 |
setStateMaximized(sa, false, true, false);
|
| 2196 |
}
|
| 2197 |
break;
|
| 2198 |
case STATE_SHADED:
|
| 2199 |
setShaded(sa);
|
| 2200 |
break;
|
| 2201 |
case STATE_HIDDEN:
|
| 2202 |
if (! client->isCfgDeny(CFG_DENY_STATE_HIDDEN)) {
|
| 2203 |
setStateIconified(sa);
|
| 2204 |
}
|
| 2205 |
break;
|
| 2206 |
case STATE_FULLSCREEN:
|
| 2207 |
if (! client->isCfgDeny(CFG_DENY_STATE_FULLSCREEN)) {
|
| 2208 |
setStateFullscreen(sa);
|
| 2209 |
}
|
| 2210 |
break;
|
| 2211 |
case STATE_ABOVE:
|
| 2212 |
if (! client->isCfgDeny(CFG_DENY_STATE_ABOVE)) {
|
| 2213 |
setStateAlwaysOnTop(sa);
|
| 2214 |
}
|
| 2215 |
break;
|
| 2216 |
case STATE_BELOW:
|
| 2217 |
if (! client->isCfgDeny(CFG_DENY_STATE_BELOW)) {
|
| 2218 |
setStateAlwaysBelow(sa);
|
| 2219 |
}
|
| 2220 |
break;
|
| 2221 |
}
|
| 2222 |
}
|
| 2223 |
|
| 2224 |
//! @brief
|
| 2225 |
void
|
| ... |
|