From d6befe5371c5df7d719cb184c4d20e38dc841a13 Mon Sep 17 00:00:00 2001 From: mathias Date: Wed, 16 Mar 2005 23:19:36 +0000 Subject: fix for gravity field on _NET_MOVERESIZE_WINDOW messages, patch from Rob Stevens --- ChangeLog | 4 ++- src/Ewmh.cc | 7 ++-- src/FbWinFrame.cc | 103 ++++++++++++++++++++++++++++++++---------------------- src/FbWinFrame.hh | 13 +++---- src/Window.cc | 23 ++++++++++++ src/Window.hh | 3 +- 6 files changed, 100 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a8e261..7a04b22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,9 @@ (Format: Year/Month/Day) Changes for 0.9.13 *05/03/16: - added new option to specify, on which screen fluxbox should handle + * fix for gravity field on _NET_MOVERESIZE_WINDOW (thanx to Rob Stevens) + Ewmh.cc, Window.(cc,hh), FbWinFrame.(cc,hh) + * added new option to specify, on which screen fluxbox should handle the windows. default behavior is to handle each available screen. closes #1159809. (Mathias) diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 34c166c..d6ccf36 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -706,9 +706,10 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, // ce.data.l[2] = y // ce.data.l[3] = width // ce.data.l[4] = height - // TODO: gravity and flags - winclient->fbwindow()->moveResize(ce.data.l[1], ce.data.l[2], - ce.data.l[3], ce.data.l[4]); + // TODO: flags + int win_gravity=ce.data.l[0] & 0xFF; + winclient->fbwindow()->moveResizeForClient(ce.data.l[1], ce.data.l[2], + ce.data.l[3], ce.data.l[4], win_gravity); return true; } diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 266f5c4..d4a3d66 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -166,16 +166,16 @@ void FbWinFrame::shade() { } -void FbWinFrame::move(int x, int y) { - moveResize(x, y, 0, 0, true, false); +void FbWinFrame::move(int x, int y, int win_gravity) { + moveResize(x, y, 0, 0, true, false, win_gravity); } -void FbWinFrame::resize(unsigned int width, unsigned int height) { - moveResize(0, 0, width, height, false, true); +void FbWinFrame::resize(unsigned int width, unsigned int height, int win_gravity) { + moveResize(0, 0, width, height, false, true, win_gravity); } // need an atomic moveresize where possible -void FbWinFrame::moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) { +void FbWinFrame::moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move, bool resize, int win_gravity) { // total height for frame unsigned int total_height = height; @@ -188,14 +188,17 @@ void FbWinFrame::moveResizeForClient(int x, int y, unsigned int width, unsigned if (m_use_handle) total_height += m_handle.height() + m_handle.borderWidth(); } - moveResize(x, y, width, total_height, move, resize); + moveResize(x, y, width, total_height, move, resize, win_gravity); } -void FbWinFrame::resizeForClient(unsigned int width, unsigned int height) { - moveResizeForClient(0, 0, width, height, false, true); +void FbWinFrame::resizeForClient(unsigned int width, unsigned int height, int win_gravity) { + moveResizeForClient(0, 0, width, height, false, true, win_gravity); } -void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int height, bool move, bool resize) { +void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int height, bool move, bool resize, int win_gravity) { + if(win_gravity!=ForgetGravity) { + gravityTranslate(x, y, width + m_window.borderWidth()*2, height + m_window.borderWidth()*2, win_gravity, false); + } if (move && x == window().x() && y == window().y()) move = false; @@ -1456,6 +1459,10 @@ void FbWinFrame::updateTransparent() { // if win_gravity is negative, it does an inverse translation // This function should be used when a window is mapped/unmapped/pos configured void FbWinFrame::gravityTranslate(int &x, int &y, int win_gravity, bool move_frame) { + gravityTranslate(x, y, m_window.width(), m_window.height(), win_gravity, move_frame); +} +//use width and height given instead of the real values, allows figuring out where to place a window before doing a moveResize +void FbWinFrame::gravityTranslate(int &x, int &y, unsigned int width, unsigned int height, int win_gravity, bool move_frame) { bool invert = false; if (win_gravity < 0) { invert = true; @@ -1483,44 +1490,57 @@ void FbWinFrame::gravityTranslate(int &x, int &y, int win_gravity, bool move_fra int x_offset = 0; int y_offset = 0; - // mostly no X offset, since we don't have extra frame on the sides - switch (win_gravity) { - case NorthWestGravity: - case NorthGravity: - case NorthEastGravity: - // no offset, since the top point is still the same - break; - case SouthWestGravity: - case SouthGravity: - case SouthEastGravity: - // window shifted down by height of titlebar, and the handle - // since that's necessary to get the bottom of the frame - // all the way up - if (m_use_titlebar) - y_offset -= m_titlebar.height() + m_titlebar.borderWidth(); - if (m_use_handle) - y_offset -= m_handle.height() + m_handle.borderWidth(); - break; - case WestGravity: - case EastGravity: - case CenterGravity: - // these centered ones are a little more interesting - if (m_use_titlebar) - y_offset -= m_titlebar.height() + m_titlebar.borderWidth(); - if (m_use_handle) - y_offset -= m_handle.height() + m_handle.borderWidth(); - y_offset /= 2; - break; - case StaticGravity: + /* win_gravity: placed at the reference point + * StaticGravity the left top corner of the client window + * NorthWestGravity the left top corner of the frame window + * NorthGravity the center of the frame window's top side + * NorthEastGravity the right top corner of the frame window + * EastGravity the center of the frame window's right side + * SouthEastGravity the right bottom corner of the frame window + * SouthGravity the center of the frame window's bottom side + * SouthWestGravity the left bottom corner of the frame window + * WestGravity the center of the frame window's left side + * CenterGravity the center of the frame window + */ + + + //vertical offset + //North Gravities don't require a vertical offset + //South Gravities + if (win_gravity==SouthWestGravity || win_gravity==SouthGravity || + win_gravity==SouthEastGravity) { + //We start on the frame so going the full height would take us one pixel past the edge of the frame + y_offset-=height-1; + } + + //vertical centering + if (win_gravity==WestGravity || win_gravity==CenterGravity || + win_gravity==EastGravity) { + y_offset-=height/2; + } + + //horizontal offset + //West Gravities don't require a horizontal offset + //East Gravities + if (win_gravity==NorthEastGravity || win_gravity==EastGravity || + win_gravity==SouthEastGravity ) { + //Starting on the frame so offset of one width would end up one pixel beyond the border + x_offset-=width-1; + } + //horizontal centering + if (win_gravity==NorthGravity || win_gravity==CenterGravity || + win_gravity==SouthGravity ) { + x_offset-=width/2; + } + + if( win_gravity==StaticGravity ) { if (m_use_titlebar) y_offset -= m_titlebar.height() + m_titlebar.borderWidth(); - // static is the only one that also has the - // border taken into account x_offset -= m_window.borderWidth(); y_offset -= m_window.borderWidth(); - break; } + if (invert) { x_offset = -x_offset; y_offset = -y_offset; @@ -1528,7 +1548,6 @@ void FbWinFrame::gravityTranslate(int &x, int &y, int win_gravity, bool move_fra x += x_offset; y += y_offset; - if (move_frame && (x_offset != 0 || y_offset != 0)) { move(x, y); } diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh index 32161d1..768f733 100644 --- a/src/FbWinFrame.hh +++ b/src/FbWinFrame.hh @@ -76,16 +76,16 @@ public: inline bool isVisible() const { return m_visible; } /// shade frame (ie resize to titlebar size) void shade(); - void move(int x, int y); - void resize(unsigned int width, unsigned int height); + void move(int x, int y, int win_gravity=ForgetGravity); + void resize(unsigned int width, unsigned int height, int win_gravity=ForgetGravity); /// resize client to specified size and resize frame to it - void resizeForClient(unsigned int width, unsigned int height); + void resizeForClient(unsigned int width, unsigned int height, int win_gravity=ForgetGravity); // for when there needs to be an atomic move+resize operation - void moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move = true, bool resize = true); + void moveResizeForClient(int x, int y, unsigned int width, unsigned int height, bool move = true, bool resize = true, int win_gravity=ForgetGravity); // can elect to ignore move or resize (mainly for use of move/resize individual functions - void moveResize(int x, int y, unsigned int width, unsigned int height, bool move = true, bool resize = true); + void moveResize(int x, int y, unsigned int width, unsigned int height, bool move = true, bool resize = true, int win_gravity=ForgetGravity); /// set focus/unfocus style void setFocus(bool newvalue); @@ -133,7 +133,8 @@ public: // this function translates its arguments according to win_gravity // if win_gravity is negative, it does an inverse translation void gravityTranslate(int &x, int &y, int win_gravity, bool move_frame = false); - + //use width and height given instead of the real values, allows figuring out where to place a window before doing a moveResize + void gravityTranslate(int &x, int &y, unsigned int width, unsigned int height, int win_gravity, bool move_frame = false); void setBorderWidth(unsigned int borderW); /** diff --git a/src/Window.cc b/src/Window.cc index 0bee703..e1fea07 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1387,6 +1387,29 @@ void FluxboxWindow::moveResize(int new_x, int new_y, } +void FluxboxWindow::moveResizeForClient(int new_x, int new_y, + unsigned int new_width, unsigned int new_height, int gravity) { + + // magic to detect if moved during initialisation + if (!isInitialized()) + m_old_pos_x = 1; + frame().moveResizeForClient(new_x, new_y, new_width, new_height, true, true, gravity); + setFocusFlag(focused); + shaded = false; + sendConfigureNotify(); + + shape(); + + if (!moving) { + m_last_resize_x = new_x; + m_last_resize_y = new_y; + } + +} + + + + // returns whether the focus was "set" to this window // it doesn't guarantee that it has focus, but says that we have // tried. A FocusqIn event should eventually arrive for that diff --git a/src/Window.hh b/src/Window.hh index ac13da6..f4a038a 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -233,7 +233,8 @@ public: void resize(unsigned int width, unsigned int height); /// move and resize frame to pox x,y and size width, height void moveResize(int x, int y, unsigned int width, unsigned int height, int gravity = ForgetGravity); - + /// move to pos x,y and resize client window to size width, height + void moveResizeForClient(int x, int y, unsigned int width, unsigned int height, int gravity = ForgetGravity); void setWorkspace(int n); void changeBlackboxHints(const BlackboxHints &bh); void updateFunctions(); -- cgit v0.11.2