fix grouping to persist over restart, plus various related bugs.

Also move a large proportion of window initialisation from FluxboxWindow to
WinClient
This commit is contained in:
rathnor 2003-06-23 14:16:05 +00:00
parent 2e6baffb9b
commit 09a5c23c5b
10 changed files with 521 additions and 296 deletions

View file

@ -1,5 +1,10 @@
(Format: Year/Month/Day) (Format: Year/Month/Day)
Changes for 0.9.4: Changes for 0.9.4:
*03/06/23:
* Add group persistence over a restart,
Move most winclient initialisation from FluxboxWindow to WinClient,
And fix a few bugs (Simon)
Screen.hh/cc WinClient.hh/cc Window.hh/cc Gnome.cc Slit.hh
*03/06/20: *03/06/20:
* Moved SlitTheme and SlitClient out from Slit.cc into new files (Henrik) * Moved SlitTheme and SlitClient out from Slit.cc into new files (Henrik)
SlitClient.hh/cc, SlitTheme.hh SlitClient.hh/cc, SlitTheme.hh

View file

@ -132,17 +132,17 @@ Approx Date: 23 June, 2003
Key Features: Key Features:
* Regular expression support in remember * Regular expression support in remember
on several attributes (Simon) on several attributes (Simon)
- Save grouping so it persists over restart (Simon) * Save grouping so it persists over restart (Simon)
- Autogrouping functionality into remember (Simon) - Autogrouping functionality into remember (Simon)
(this will thus get regexp matching etc) (this will thus get regexp matching etc)
+ Shaped menu/slit/toolbar (Henrik) + Shaped menu/slit/toolbar (Henrik)
- Improved screen object placement (?) * Improved screen object placement (Henrik)
(will fix Maximize over slit/toolbar) (will fix Maximize over slit/toolbar)
Other Minor Features: Other Minor Features:
- Add some sort of program launch function (Simon) - Add some sort of program launch function (Simon)
- nls code - layers, remember, new stuff... (Both) - nls code - layers, remember, new stuff... (Both)
Bugfixes/lower priority: Bugfixes/lower priority:
- Titlebar sometimes doesn't redraw properly * Titlebar sometimes doesn't redraw properly
- Fixes for 0.9.3 and previous (Both) - Fixes for 0.9.3 and previous (Both)
---------------------------------------------------------- ----------------------------------------------------------

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: Gnome.cc,v 1.26 2003/06/12 14:28:00 fluxgen Exp $ // $Id: Gnome.cc,v 1.27 2003/06/23 14:16:04 rathnor Exp $
#include "Gnome.hh" #include "Gnome.hh"
@ -223,7 +223,11 @@ void Gnome::updateWorkspace(FluxboxWindow &win) {
cerr<<__FILE__<<"("<<__LINE__<<"): setting workspace("<<val<< cerr<<__FILE__<<"("<<__LINE__<<"): setting workspace("<<val<<
") for window("<<&win<<")"<<endl; ") for window("<<&win<<")"<<endl;
#endif // DEBUG #endif // DEBUG
win.winClient().changeProperty(m_gnome_wm_win_workspace,
FluxboxWindow::ClientList::iterator client_it = win.clientList().begin();
FluxboxWindow::ClientList::iterator client_it_end = win.clientList().end();
for (; client_it != client_it_end; ++client_it)
(*client_it)->changeProperty(m_gnome_wm_win_workspace,
XA_CARDINAL, 32, PropModeReplace, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *)&val, 1); (unsigned char *)&val, 1);
} }
@ -238,7 +242,10 @@ void Gnome::updateState(FluxboxWindow &win) {
if (win.isShaded()) if (win.isShaded())
state |= WIN_STATE_SHADED; state |= WIN_STATE_SHADED;
win.winClient().changeProperty(m_gnome_wm_win_state, FluxboxWindow::ClientList::iterator client_it = win.clientList().begin();
FluxboxWindow::ClientList::iterator client_it_end = win.clientList().end();
for (; client_it != client_it_end; ++client_it)
(*client_it)->changeProperty(m_gnome_wm_win_state,
XA_CARDINAL, 32, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&state, 1); PropModeReplace, (unsigned char *)&state, 1);
} }
@ -247,7 +254,11 @@ void Gnome::updateLayer(FluxboxWindow &win) {
//TODO - map from flux layers to gnome ones //TODO - map from flux layers to gnome ones
// our layers are in the opposite direction to GNOME // our layers are in the opposite direction to GNOME
int layernum = Fluxbox::instance()->getDesktopLayer() - win.layerNum(); int layernum = Fluxbox::instance()->getDesktopLayer() - win.layerNum();
win.winClient().changeProperty(m_gnome_wm_win_layer,
FluxboxWindow::ClientList::iterator client_it = win.clientList().begin();
FluxboxWindow::ClientList::iterator client_it_end = win.clientList().end();
for (; client_it != client_it_end; ++client_it)
(*client_it)->changeProperty(m_gnome_wm_win_layer,
XA_CARDINAL, 32, PropModeReplace, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *)&layernum, 1); (unsigned char *)&layernum, 1);

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: Screen.cc,v 1.189 2003/06/23 13:31:47 fluxgen Exp $ // $Id: Screen.cc,v 1.190 2003/06/23 14:16:04 rathnor Exp $
#include "Screen.hh" #include "Screen.hh"
@ -835,6 +835,16 @@ void BScreen::removeClient(WinClient &client) {
for_each(getWorkspacesList().begin(), getWorkspacesList().end(), for_each(getWorkspacesList().begin(), getWorkspacesList().end(),
mem_fun(&Workspace::updateClientmenu)); mem_fun(&Workspace::updateClientmenu));
// remove any grouping this is expecting
Groupables::iterator it = m_expecting_groups.begin();
Groupables::iterator it_end = m_expecting_groups.end();
for (; it != it_end; ++it) {
if (it->second == &client) {
m_expecting_groups.erase(it);
// it should only be in there a maximum of once
break;
}
}
} }
FluxboxWindow *BScreen::getIcon(unsigned int index) { FluxboxWindow *BScreen::getIcon(unsigned int index) {
@ -1106,23 +1116,31 @@ void BScreen::updateNetizenConfigNotify(XEvent *e) {
} }
FluxboxWindow *BScreen::createWindow(Window client) { FluxboxWindow *BScreen::createWindow(Window client) {
FluxboxWindow *win = new FluxboxWindow(client, *this, WinClient *winclient = new WinClient(client, *this);
winFrameTheme(), *menuTheme(),
*layerManager().getLayer(Fluxbox::instance()->getNormalLayer()));
#ifdef SLIT #ifdef SLIT
if (win->initialState() == WithdrawnState) { if (winclient->initial_state == WithdrawnState) {
delete win; delete winclient;
win = 0;
slit()->addClient(client); slit()->addClient(client);
return 0; return 0;
} }
#endif // SLIT #endif // SLIT
// check if it should be grouped with something else
FluxboxWindow *win;
if ((win = findGroupLeft(*winclient)) != 0) {
win->attachClient(*winclient);
} else {
win = new FluxboxWindow(*winclient, *this,
winFrameTheme(), *menuTheme(),
*layerManager().getLayer(Fluxbox::instance()->getNormalLayer()));
}
if (!win->isManaged()) { if (!win->isManaged()) {
delete win; delete win;
return 0; return 0;
} else { } else {
// always put on end of focused list, if it gets focused it'll get pushed up // always put on end of focused list, if it gets focused it'll get pushed up
// there is only the one win client at this stage // there is only the one win client at this stage
if (doFocusNew()) if (doFocusNew())
@ -1135,9 +1153,18 @@ FluxboxWindow *BScreen::createWindow(Window client) {
setupWindowActions(*win); setupWindowActions(*win);
Fluxbox::instance()->attachSignals(*win); Fluxbox::instance()->attachSignals(*win);
} }
if (win->workspaceNumber() == currentWorkspaceID() || win->isStuck()) {
// we also need to check if another window expects this window to the left
// and if so, then join it.
FluxboxWindow *otherwin = 0;
// TODO: does this do the right stuff focus-wise?
if ((otherwin = findGroupRight(*winclient)) && otherwin != win)
win->attachClient(otherwin->winClient());
if (!win->isIconic() && (win->workspaceNumber() == currentWorkspaceID() || win->isStuck())) {
win->show(); win->show();
} }
XSync(FbTk::App::instance()->display(), False); XSync(FbTk::App::instance()->display(), False);
return win; return win;
} }
@ -2349,10 +2376,16 @@ void BScreen::notifyReleasedKeys(XKeyEvent &ke) {
cycling_focus = false; cycling_focus = false;
cycling_last = 0; cycling_last = 0;
// put currently focused window to top // put currently focused window to top
// the iterator may be invalid if the window died
// in which case we'll do a proper revert focus
if (cycling_window != focused_list.end()) {
WinClient *client = *cycling_window; WinClient *client = *cycling_window;
focused_list.erase(cycling_window); focused_list.erase(cycling_window);
focused_list.push_front(client); focused_list.push_front(client);
client->fbwindow()->raise(); client->fbwindow()->raise();
} else {
Fluxbox::instance()->revertFocus(*this);
}
} }
} }
@ -2407,6 +2440,45 @@ void BScreen::updateSize() {
} }
/**
* Find the group of windows to this window's left
* So, we check the leftgroup hint, and see if we know any windows
*/
FluxboxWindow *BScreen::findGroupLeft(WinClient &winclient) {
Window w = winclient.getGroupLeftWindow();
if (w == None)
return 0;
FluxboxWindow *fbwin = Fluxbox::instance()->searchWindow(w);
if (!fbwin) {
// not found, add it to expecting
m_expecting_groups[w] = &winclient;
} else if (&fbwin->screen() != &winclient.screen())
// something is not consistent
return 0;
return fbwin;
}
FluxboxWindow *BScreen::findGroupRight(WinClient &winclient) {
Groupables::iterator it = m_expecting_groups.find(winclient.window());
if (it == m_expecting_groups.end())
return 0;
// yay, this'll do.
WinClient *other = it->second;
m_expecting_groups.erase(it); // don't expect it anymore
// forget about it if it isn't the left-most client in the group, plus
// it must have the atom set on it (i.e. previously encountered by fluxbox)
// for us to check our expecting
if (!winclient.hasGroupLeftWindow() ||
other->getGroupLeftWindow() != None)
return 0;
return other->m_win;
}
void BScreen::initXinerama() { void BScreen::initXinerama() {
#ifdef XINERAMA #ifdef XINERAMA
Display *display = FbTk::App::instance()->display(); Display *display = FbTk::App::instance()->display();
@ -2544,3 +2616,17 @@ void BScreen::setOnHead<Toolbar>(Toolbar &tbar, int head) {
tbar.reconfigure(); tbar.reconfigure();
} }
// TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then
// this can be gone and a consistent interface for the two used
// on the actual objects
template <>
int BScreen::getOnHead<Slit>(Slit &slit) {
return slit.getOnHead();
}
template <>
void BScreen::setOnHead<Slit>(Slit &slit, int head) {
slit.saveOnHead(head);
slit.reconfigure();
}

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: Screen.hh,v 1.108 2003/06/23 12:57:36 fluxgen Exp $ // $Id: Screen.hh,v 1.109 2003/06/23 14:16:04 rathnor Exp $
#ifndef SCREEN_HH #ifndef SCREEN_HH
#define SCREEN_HH #define SCREEN_HH
@ -295,6 +295,12 @@ public:
template <typename OnHeadObject> template <typename OnHeadObject>
void setOnHead(OnHeadObject &obj, int head); void setOnHead(OnHeadObject &obj, int head);
// grouping - we want ordering, so we can either search for a
// group to the left, or to the right (they'll be different if
// they exist).
FluxboxWindow *findGroupLeft(WinClient &winclient);
FluxboxWindow *findGroupRight(WinClient &winclient);
// notify netizens // notify netizens
void updateNetizenCurrentWorkspace(); void updateNetizenCurrentWorkspace();
void updateNetizenWorkspaceCount(); void updateNetizenWorkspaceCount();
@ -419,6 +425,11 @@ private:
} resource; } resource;
// This is a map of windows to clients for clients that had a left
// window set, but that window wasn't present at the time
typedef std::map<Window, WinClient *> Groupables;
Groupables m_expecting_groups;
const std::string m_name, m_altname; const std::string m_name, m_altname;
FbTk::ResourceManager &m_resource_manager; FbTk::ResourceManager &m_resource_manager;

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
/// $Id: Slit.hh,v 1.33 2003/06/22 12:32:08 fluxgen Exp $ /// $Id: Slit.hh,v 1.34 2003/06/23 14:16:04 rathnor Exp $
#ifndef SLIT_HH #ifndef SLIT_HH
#define SLIT_HH #define SLIT_HH
@ -67,6 +67,8 @@ public:
inline bool doAutoHide() const { return *m_rc_auto_hide; } inline bool doAutoHide() const { return *m_rc_auto_hide; }
inline Direction direction() const { return *m_rc_direction; } inline Direction direction() const { return *m_rc_direction; }
inline Placement placement() const { return *m_rc_placement; } inline Placement placement() const { return *m_rc_placement; }
inline int getOnHead() const { return *m_rc_on_head; }
inline void saveOnHead(int head) { m_rc_on_head = head; }
FbTk::Menu &menu() { return m_slitmenu; } FbTk::Menu &menu() { return m_slitmenu; }
inline const FbTk::FbWindow &window() const { return frame.window; } inline const FbTk::FbWindow &window() const { return frame.window; }

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: WinClient.cc,v 1.13 2003/06/22 12:35:03 fluxgen Exp $ // $Id: WinClient.cc,v 1.14 2003/06/23 14:16:05 rathnor Exp $
#include "WinClient.hh" #include "WinClient.hh"
@ -38,7 +38,7 @@
using namespace std; using namespace std;
WinClient::WinClient(Window win, FluxboxWindow &fbwin):FbTk::FbWindow(win), WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::FbWindow(win),
transient_for(0), transient_for(0),
window_group(0), window_group(0),
x(0), y(0), old_bw(0), x(0), y(0), old_bw(0),
@ -52,12 +52,20 @@ WinClient::WinClient(Window win, FluxboxWindow &fbwin):FbTk::FbWindow(win),
initial_state(0), initial_state(0),
normal_hint_flags(0), normal_hint_flags(0),
wm_hint_flags(0), wm_hint_flags(0),
mwm_hint(0), send_focus_message(false),
blackbox_hint(0), m_win(fbwin),
m_win(&fbwin),
modal(false), modal(false),
m_title(""), m_icon_title(""), m_title(""), m_icon_title(""),
m_diesig(*this), m_screen(fbwin.screen()) { } m_class_name(""), m_instance_name(""),
m_blackbox_hint(0),
m_mwm_hint(0),
m_focus_mode(F_PASSIVE),
m_diesig(*this), m_screen(screen) {
updateBlackboxHints();
updateMWMHints();
updateWMHints();
updateWMNormalHints();
}
WinClient::~WinClient() { WinClient::~WinClient() {
#ifdef DEBUG #ifdef DEBUG
@ -90,11 +98,11 @@ WinClient::~WinClient() {
window_group = 0; window_group = 0;
} }
if (mwm_hint != 0) if (m_mwm_hint != 0)
XFree(mwm_hint); XFree(m_mwm_hint);
if (blackbox_hint != 0) if (m_blackbox_hint != 0)
XFree(blackbox_hint); XFree(m_blackbox_hint);
if (window()) if (window())
fluxbox->removeWindowSearch(window()); fluxbox->removeWindowSearch(window());
@ -126,6 +134,9 @@ void WinClient::updateRect(int x, int y,
} }
void WinClient::sendFocus() { void WinClient::sendFocus() {
if (!send_focus_message)
return;
Display *disp = FbTk::App::instance()->display(); Display *disp = FbTk::App::instance()->display();
// setup focus msg // setup focus msg
XEvent ce; XEvent ce;
@ -288,3 +299,212 @@ void WinClient::updateIconTitle() {
m_icon_title = title(); m_icon_title = title();
} }
void WinClient::saveBlackboxAttribs(FluxboxWindow::BlackboxAttributes &blackbox_attribs) {
changeProperty(FbAtoms::instance()->getFluxboxAttributesAtom(),
PropModeReplace, XA_CARDINAL, 32,
(unsigned char *)&blackbox_attribs,
FluxboxWindow::PropBlackboxAttributesElements
);
}
void WinClient::updateBlackboxHints() {
int format;
Atom atom_return;
unsigned long num, len;
FbAtoms *atoms = FbAtoms::instance();
if (m_blackbox_hint) {
XFree(m_blackbox_hint);
m_blackbox_hint = 0;
}
if (property(atoms->getFluxboxHintsAtom(), 0,
PropBlackboxHintsElements, False,
atoms->getFluxboxHintsAtom(), &atom_return,
&format, &num, &len,
(unsigned char **) &m_blackbox_hint) &&
m_blackbox_hint) {
if (num != (unsigned)PropBlackboxHintsElements) {
XFree(m_blackbox_hint);
m_blackbox_hint = 0;
}
}
}
void WinClient::updateMWMHints() {
int format;
Atom atom_return;
unsigned long num = 0, len = 0;
Atom motif_wm_hints = XInternAtom(FbTk::App::instance()->display(), "_MOTIF_WM_HINTS", False);
if (m_mwm_hint) {
XFree(m_mwm_hint);
m_mwm_hint = 0;
}
if (!(property(motif_wm_hints, 0,
PropMwmHintsElements, false,
motif_wm_hints, &atom_return,
&format, &num, &len,
(unsigned char **) &m_mwm_hint) &&
m_mwm_hint)) {
if (num != static_cast<unsigned int>(PropMwmHintsElements)) {
XFree(m_mwm_hint);
m_mwm_hint = 0;
return;
}
}
}
void WinClient::updateWMHints() {
XWMHints *wmhint = XGetWMHints(FbTk::App::instance()->display(), window());
if (! wmhint) {
m_focus_mode = F_PASSIVE;
window_group = None;
initial_state = NormalState;
} else {
wm_hint_flags = wmhint->flags;
if (wmhint->flags & InputHint) {
if (wmhint->input) {
if (send_focus_message)
m_focus_mode = F_LOCALLYACTIVE;
else
m_focus_mode = F_PASSIVE;
} else {
if (send_focus_message)
m_focus_mode = F_GLOBALLYACTIVE;
else
m_focus_mode = F_NOINPUT;
}
} else
m_focus_mode = F_PASSIVE;
if (wmhint->flags & StateHint)
initial_state = wmhint->initial_state;
else
initial_state = NormalState;
if (wmhint->flags & WindowGroupHint) {
if (! window_group)
window_group = wmhint->window_group;
} else
window_group = None;
XFree(wmhint);
}
}
void WinClient::updateWMNormalHints() {
long icccm_mask;
XSizeHints sizehint;
if (! XGetWMNormalHints(FbTk::App::instance()->display(), window(), &sizehint, &icccm_mask)) {
min_width = min_height =
base_width = base_height =
width_inc = height_inc = 1;
max_width = 0; // unbounded
max_height = 0;
min_aspect_x = min_aspect_y =
max_aspect_x = max_aspect_y = 1;
win_gravity = NorthWestGravity;
} else {
normal_hint_flags = sizehint.flags;
if (sizehint.flags & PMinSize) {
min_width = sizehint.min_width;
min_height = sizehint.min_height;
} else
min_width = min_height = 1;
if (sizehint.flags & PMaxSize) {
max_width = sizehint.max_width;
max_height = sizehint.max_height;
} else {
max_width = 0; // unbounded
max_height = 0;
}
if (sizehint.flags & PResizeInc) {
width_inc = sizehint.width_inc;
height_inc = sizehint.height_inc;
} else
width_inc = height_inc = 1;
if (sizehint.flags & PAspect) {
min_aspect_x = sizehint.min_aspect.x;
min_aspect_y = sizehint.min_aspect.y;
max_aspect_x = sizehint.max_aspect.x;
max_aspect_y = sizehint.max_aspect.y;
} else
min_aspect_x = min_aspect_y =
max_aspect_x = max_aspect_y = 1;
if (sizehint.flags & PBaseSize) {
base_width = sizehint.base_width;
base_height = sizehint.base_height;
} else
base_width = base_height = 0;
if (sizehint.flags & PWinGravity)
win_gravity = sizehint.win_gravity;
else
win_gravity = NorthWestGravity;
}
}
Window WinClient::getGroupLeftWindow() const {
int format;
Atom atom_return;
unsigned long num = 0, len = 0;
Atom group_left_hint = XInternAtom(FbTk::App::instance()->display(), "_FLUXBOX_GROUP_LEFT", False);
Window *data = 0;
if (property(group_left_hint, 0,
1, false,
XA_WINDOW, &atom_return,
&format, &num, &len,
(unsigned char **) &data) &&
data) {
if (num != 1) {
XFree(data);
return None;
} else {
Window ret = *data;
XFree(data);
return ret;
}
}
return None;
}
void WinClient::setGroupLeftWindow(Window win) {
Atom group_left_hint = XInternAtom(FbTk::App::instance()->display(), "_FLUXBOX_GROUP_LEFT", False);
changeProperty(group_left_hint, XA_WINDOW, 32,
PropModeReplace, (unsigned char *) &win, 1);
}
bool WinClient::hasGroupLeftWindow() const {
int format;
Atom atom_return;
unsigned long num = 0, len = 0;
Atom group_left_hint = XInternAtom(FbTk::App::instance()->display(), "_FLUXBOX_GROUP_LEFT", False);
Window *data = 0;
if (property(group_left_hint, 0,
1, false,
XA_WINDOW, &atom_return,
&format, &num, &len,
(unsigned char **) &data) &&
data) {
if (num != 1) {
XFree(data);
return false;
} else {
XFree(data);
return true;
}
}
return false;
}

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: WinClient.hh,v 1.7 2003/06/15 18:36:40 fluxgen Exp $ // $Id: WinClient.hh,v 1.8 2003/06/23 14:16:05 rathnor Exp $
#ifndef WINCLIENT_HH #ifndef WINCLIENT_HH
#define WINCLIENT_HH #define WINCLIENT_HH
@ -38,7 +38,7 @@ class WinClient:public FbTk::FbWindow {
public: public:
typedef std::list<WinClient *> TransientList; typedef std::list<WinClient *> TransientList;
WinClient(Window win, FluxboxWindow &fbwin); WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin = 0);
~WinClient(); ~WinClient();
void updateRect(int x, int y, unsigned int width, unsigned int height); void updateRect(int x, int y, unsigned int width, unsigned int height);
@ -80,6 +80,20 @@ public:
const std::string &iconTitle() const { return m_icon_title; } const std::string &iconTitle() const { return m_icon_title; }
const FluxboxWindow *fbwindow() const { return m_win; } const FluxboxWindow *fbwindow() const { return m_win; }
FluxboxWindow *fbwindow() { return m_win; } FluxboxWindow *fbwindow() { return m_win; }
static const int PropBlackboxHintsElements = 5;
static const int PropMwmHintsElements = 3;
void updateBlackboxHints();
void updateMWMHints();
void updateWMHints();
void updateWMNormalHints();
// grouping is tracked by remembering the window to the left in the group
Window getGroupLeftWindow() const;
void setGroupLeftWindow(Window win);
bool hasGroupLeftWindow() const;
/** /**
!! TODO !! !! TODO !!
remove or move these to private remove or move these to private
@ -96,6 +110,7 @@ public:
min_aspect_x, min_aspect_y, max_aspect_x, max_aspect_y, min_aspect_x, min_aspect_y, max_aspect_x, max_aspect_y,
base_width, base_height, win_gravity; base_width, base_height, win_gravity;
unsigned long initial_state, normal_hint_flags, wm_hint_flags; unsigned long initial_state, normal_hint_flags, wm_hint_flags;
bool send_focus_message;
// this structure only contains 3 elements... the Motif 2.0 structure contains // this structure only contains 3 elements... the Motif 2.0 structure contains
// 5... we only need the first 3... so that is all we will define // 5... we only need the first 3... so that is all we will define
@ -105,8 +120,6 @@ public:
unsigned long decorations; // Motif wm decorations unsigned long decorations; // Motif wm decorations
} MwmHints; } MwmHints;
MwmHints *mwm_hint;
FluxboxWindow::BlackboxHints *blackbox_hint;
FluxboxWindow *m_win; FluxboxWindow *m_win;
class WinClientSubj: public FbTk::Subject { class WinClientSubj: public FbTk::Subject {
public: public:
@ -116,12 +129,28 @@ public:
WinClient &m_winclient; WinClient &m_winclient;
}; };
inline int getFocusMode() const { return m_focus_mode; }
inline const FluxboxWindow::BlackboxHints *getBlackboxHint() const {
return m_blackbox_hint; }
void saveBlackboxAttribs(FluxboxWindow::BlackboxAttributes &blackbox_attribs);
inline const MwmHints *getMwmHint() const { return m_mwm_hint; }
enum { F_NOINPUT = 0, F_PASSIVE, F_LOCALLYACTIVE, F_GLOBALLYACTIVE };
private: private:
bool modal; bool modal;
std::string m_title, m_icon_title; std::string m_title, m_icon_title;
std::string m_class_name, m_instance_name;
FluxboxWindow::BlackboxHints *m_blackbox_hint;
MwmHints *m_mwm_hint;
int m_focus_mode;
WinClientSubj m_diesig; WinClientSubj m_diesig;
BScreen &m_screen; BScreen &m_screen;
std::string m_class_name, m_instance_name;
}; };
#endif // WINCLIENT_HH #endif // WINCLIENT_HH

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: Window.cc,v 1.194 2003/06/22 21:29:32 fluxgen Exp $ // $Id: Window.cc,v 1.195 2003/06/23 14:16:05 rathnor Exp $
#include "Window.hh" #include "Window.hh"
@ -61,6 +61,8 @@
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <functional>
#include <algorithm>
using namespace std; using namespace std;
@ -232,7 +234,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &t
m_diesig(*this), m_diesig(*this),
moving(false), resizing(false), shaded(false), maximized(false), moving(false), resizing(false), shaded(false), maximized(false),
iconic(false), focused(false), iconic(false), focused(false),
stuck(false), send_focus_message(false), m_managed(false), stuck(false), m_managed(false),
m_screen(scr), m_screen(scr),
m_timer(this), m_timer(this),
display(0), display(0),
@ -255,42 +257,6 @@ FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &t
} }
FluxboxWindow::FluxboxWindow(Window w, BScreen &scr, FbWinFrameTheme &tm,
FbTk::MenuTheme &menutheme,
FbTk::XLayer &layer):
oplock(false),
m_hintsig(*this),
m_statesig(*this),
m_layersig(*this),
m_workspacesig(*this),
m_diesig(*this),
moving(false), resizing(false), shaded(false), maximized(false),
iconic(false), focused(false),
stuck(false), send_focus_message(false), m_managed(false),
m_screen(scr),
m_timer(this),
display(0),
m_layermenu(new LayerMenu<FluxboxWindow>(menutheme,
scr.screenNumber(),
scr.imageControl(),
*scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
this,
false)),
m_windowmenu(menutheme, scr.screenNumber(), scr.imageControl()),
m_old_decoration(DECOR_NORMAL),
m_client(new WinClient(w, *this)),
m_frame(new FbWinFrame(tm, scr.imageControl(), scr.screenNumber(), 0, 0, 100, 100)),
m_strut(0),
m_layeritem(m_frame->window(), layer),
m_layernum(layer.getLayerNum()),
m_parent(scr.rootWindow()) {
assert(w != 0);
init();
}
FluxboxWindow::~FluxboxWindow() { FluxboxWindow::~FluxboxWindow() {
#ifdef DEBUG #ifdef DEBUG
cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<")"<<endl; cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<")"<<endl;
@ -344,7 +310,10 @@ void FluxboxWindow::init() {
m_layermenu->setInternalMenu(); m_layermenu->setInternalMenu();
m_attaching_tab = 0; m_attaching_tab = 0;
assert(m_client); assert(m_client);
m_client->m_win = this;
m_client->setGroupLeftWindow(None); // nothing to the left.
// check for shape extension and whether the window is shaped // check for shape extension and whether the window is shaped
m_shaped = false; m_shaped = false;
@ -433,16 +402,17 @@ void FluxboxWindow::init() {
functions.resize = functions.move = functions.iconify = functions.maximize = true; functions.resize = functions.move = functions.iconify = functions.maximize = true;
functions.close = decorations.close = false; functions.close = decorations.close = false;
if (m_client->getBlackboxHint() != 0)
getBlackboxHints(); getBlackboxHints();
if (! m_client->blackbox_hint) else
getMWMHints(); getMWMHints();
// get size, aspect, minimum/maximum size and other hints set // get size, aspect, minimum/maximum size and other hints set
// by the client // by the client
getWMProtocols(); getWMProtocols();
getWMHints(); if (m_client->window_group != None)
getWMNormalHints(); Fluxbox::instance()->saveGroupSearch(m_client->window_group, this);
//!! //!!
// fetch client size and placement // fetch client size and placement
@ -589,13 +559,23 @@ void FluxboxWindow::attachClient(WinClient &client) {
frame().setClientWindow(client); frame().setClientWindow(client);
FbTk::EventManager &evm = *FbTk::EventManager::instance(); FbTk::EventManager &evm = *FbTk::EventManager::instance();
// get the current window on the end of our client list
Window leftwin = None;
ClientList::iterator client_it = clientList().end();
ClientList::iterator client_it_end = clientList().end();
--client_it;
if (client_it != client_it_end)
leftwin = (*client_it)->window();
client.setGroupLeftWindow(leftwin);
if (client.fbwindow() != 0) { if (client.fbwindow() != 0) {
FluxboxWindow *old_win = client.fbwindow(); // store old window FluxboxWindow *old_win = client.fbwindow(); // store old window
Fluxbox *fb = Fluxbox::instance(); Fluxbox *fb = Fluxbox::instance();
// make sure we set new window search for each client // make sure we set new window search for each client
ClientList::iterator client_it = old_win->clientList().begin(); client_it = old_win->clientList().begin();
ClientList::iterator client_it_end = old_win->clientList().end(); client_it_end = old_win->clientList().end();
for (; client_it != client_it_end; ++client_it) { for (; client_it != client_it_end; ++client_it) {
// setup eventhandlers for client // setup eventhandlers for client
fb->saveWindowSearch((*client_it)->window(), this); fb->saveWindowSearch((*client_it)->window(), this);
@ -628,10 +608,12 @@ void FluxboxWindow::attachClient(WinClient &client) {
btn->setOnClick(set_client_cmd); btn->setOnClick(set_client_cmd);
evm.add(*this, btn->window()); // we take care of button events for this evm.add(*this, btn->window()); // we take care of button events for this
(*client_it)->saveBlackboxAttribs(m_blackbox_attrib);
} }
// add client and move over all attached clients // add client and move over all attached clients
// from the old window to this list // from the old window to this list
// all the "left window"s will remain the same, except for the first.
m_clientlist.splice(m_clientlist.end(), old_win->m_clientlist); m_clientlist.splice(m_clientlist.end(), old_win->m_clientlist);
old_win->m_client = 0; old_win->m_client = 0;
@ -659,8 +641,16 @@ void FluxboxWindow::attachClient(WinClient &client) {
client.m_win = this; client.m_win = this;
Fluxbox::instance()->saveWindowSearch(client.window(), this); Fluxbox::instance()->saveWindowSearch(client.window(), this);
client.saveBlackboxAttribs(m_blackbox_attrib);
} }
// make sure that the state etc etc is updated for the new client
// TODO: one day these should probably be neatened to only act on the
// affected clients if possible
m_statesig.notify();
m_workspacesig.notify();
m_layersig.notify();
frame().reconfigure(); frame().reconfigure();
// keep the current window on top // keep the current window on top
@ -889,7 +879,7 @@ void FluxboxWindow::getWMProtocols() {
if (proto[i] == fbatoms->getWMDeleteAtom()) if (proto[i] == fbatoms->getWMDeleteAtom())
functions.close = true; functions.close = true;
else if (proto[i] == fbatoms->getWMTakeFocusAtom()) else if (proto[i] == fbatoms->getWMTakeFocusAtom())
send_focus_message = true; m_client->send_focus_message = true;
else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom()) else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom())
screen().addNetizen(m_client->window()); screen().addNetizen(m_client->window());
} }
@ -902,125 +892,13 @@ void FluxboxWindow::getWMProtocols() {
} }
void FluxboxWindow::getWMHints() {
//!!
XWMHints *wmhint = XGetWMHints(display, m_client->window());
if (! wmhint) {
iconic = false;
m_focus_mode = F_PASSIVE;
m_client->window_group = None;
m_client->initial_state = NormalState;
} else {
m_client->wm_hint_flags = wmhint->flags;
if (wmhint->flags & InputHint) {
if (wmhint->input) {
if (send_focus_message)
m_focus_mode = F_LOCALLYACTIVE;
else
m_focus_mode = F_PASSIVE;
} else {
if (send_focus_message)
m_focus_mode = F_GLOBALLYACTIVE;
else
m_focus_mode = F_NOINPUT;
}
} else
m_focus_mode = F_PASSIVE;
if (wmhint->flags & StateHint)
m_client->initial_state = wmhint->initial_state;
else
m_client->initial_state = NormalState;
if (wmhint->flags & WindowGroupHint) {
if (! m_client->window_group) {
m_client->window_group = wmhint->window_group;
Fluxbox::instance()->saveGroupSearch(m_client->window_group, this);
}
} else
m_client->window_group = None;
XFree(wmhint);
}
}
void FluxboxWindow::getWMNormalHints() {
long icccm_mask;
XSizeHints sizehint;
if (! XGetWMNormalHints(display, m_client->window(), &sizehint, &icccm_mask)) {
m_client->min_width = m_client->min_height =
m_client->base_width = m_client->base_height =
m_client->width_inc = m_client->height_inc = 1;
m_client->max_width = 0; // unbounded
m_client->max_height = 0;
m_client->min_aspect_x = m_client->min_aspect_y =
m_client->max_aspect_x = m_client->max_aspect_y = 1;
m_client->win_gravity = NorthWestGravity;
} else {
m_client->normal_hint_flags = sizehint.flags;
if (sizehint.flags & PMinSize) {
m_client->min_width = sizehint.min_width;
m_client->min_height = sizehint.min_height;
} else
m_client->min_width = m_client->min_height = 1;
if (sizehint.flags & PMaxSize) {
m_client->max_width = sizehint.max_width;
m_client->max_height = sizehint.max_height;
} else {
m_client->max_width = 0; // unbounded
m_client->max_height = 0;
}
if (sizehint.flags & PResizeInc) {
m_client->width_inc = sizehint.width_inc;
m_client->height_inc = sizehint.height_inc;
} else
m_client->width_inc = m_client->height_inc = 1;
if (sizehint.flags & PAspect) {
m_client->min_aspect_x = sizehint.min_aspect.x;
m_client->min_aspect_y = sizehint.min_aspect.y;
m_client->max_aspect_x = sizehint.max_aspect.x;
m_client->max_aspect_y = sizehint.max_aspect.y;
} else
m_client->min_aspect_x = m_client->min_aspect_y =
m_client->max_aspect_x = m_client->max_aspect_y = 1;
if (sizehint.flags & PBaseSize) {
m_client->base_width = sizehint.base_width;
m_client->base_height = sizehint.base_height;
} else
m_client->base_width = m_client->base_height = 0;
if (sizehint.flags & PWinGravity)
m_client->win_gravity = sizehint.win_gravity;
else
m_client->win_gravity = NorthWestGravity;
}
}
void FluxboxWindow::getMWMHints() { void FluxboxWindow::getMWMHints() {
int format; const WinClient::MwmHints *hint = m_client->getMwmHint();
Atom atom_return;
unsigned long num, len;
Atom motif_wm_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False);
if (!(m_client->property(motif_wm_hints, 0,
PropMwmHintsElements, false,
motif_wm_hints, &atom_return,
&format, &num, &len,
(unsigned char **) &m_client->mwm_hint) &&
m_client->mwm_hint)) {
return;
}
if (num != static_cast<unsigned int>(PropMwmHintsElements))
return;
if (m_client->mwm_hint->flags & MwmHintsDecorations) { if (!hint) return;
if (m_client->mwm_hint->decorations & MwmDecorAll) {
if (hint->flags & MwmHintsDecorations) {
if (hint->decorations & MwmDecorAll) {
decorations.titlebar = decorations.handle = decorations.border = decorations.titlebar = decorations.handle = decorations.border =
decorations.iconify = decorations.maximize = decorations.iconify = decorations.maximize =
decorations.close = decorations.menu = true; decorations.close = decorations.menu = true;
@ -1029,41 +907,41 @@ void FluxboxWindow::getMWMHints() {
decorations.iconify = decorations.maximize = decorations.iconify = decorations.maximize =
decorations.close = decorations.tab = false; decorations.close = decorations.tab = false;
decorations.menu = true; decorations.menu = true;
if (m_client->mwm_hint->decorations & MwmDecorBorder) if (hint->decorations & MwmDecorBorder)
decorations.border = true; decorations.border = true;
if (m_client->mwm_hint->decorations & MwmDecorHandle) if (hint->decorations & MwmDecorHandle)
decorations.handle = true; decorations.handle = true;
if (m_client->mwm_hint->decorations & MwmDecorTitle) { if (hint->decorations & MwmDecorTitle) {
//only tab on windows with titlebar //only tab on windows with titlebar
decorations.titlebar = decorations.tab = true; decorations.titlebar = decorations.tab = true;
} }
if (m_client->mwm_hint->decorations & MwmDecorMenu) if (hint->decorations & MwmDecorMenu)
decorations.menu = true; decorations.menu = true;
if (m_client->mwm_hint->decorations & MwmDecorIconify) if (hint->decorations & MwmDecorIconify)
decorations.iconify = true; decorations.iconify = true;
if (m_client->mwm_hint->decorations & MwmDecorMaximize) if (hint->decorations & MwmDecorMaximize)
decorations.maximize = true; decorations.maximize = true;
} }
} }
if (m_client->mwm_hint->flags & MwmHintsFunctions) { if (hint->flags & MwmHintsFunctions) {
if (m_client->mwm_hint->functions & MwmFuncAll) { if (hint->functions & MwmFuncAll) {
functions.resize = functions.move = functions.iconify = functions.resize = functions.move = functions.iconify =
functions.maximize = functions.close = true; functions.maximize = functions.close = true;
} else { } else {
functions.resize = functions.move = functions.iconify = functions.resize = functions.move = functions.iconify =
functions.maximize = functions.close = false; functions.maximize = functions.close = false;
if (m_client->mwm_hint->functions & MwmFuncResize) if (hint->functions & MwmFuncResize)
functions.resize = true; functions.resize = true;
if (m_client->mwm_hint->functions & MwmFuncMove) if (hint->functions & MwmFuncMove)
functions.move = true; functions.move = true;
if (m_client->mwm_hint->functions & MwmFuncIconify) if (hint->functions & MwmFuncIconify)
functions.iconify = true; functions.iconify = true;
if (m_client->mwm_hint->functions & MwmFuncMaximize) if (hint->functions & MwmFuncMaximize)
functions.maximize = true; functions.maximize = true;
if (m_client->mwm_hint->functions & MwmFuncClose) if (hint->functions & MwmFuncClose)
functions.close = true; functions.close = true;
} }
} }
@ -1073,52 +951,39 @@ void FluxboxWindow::getMWMHints() {
void FluxboxWindow::getBlackboxHints() { void FluxboxWindow::getBlackboxHints() {
int format; const FluxboxWindow::BlackboxHints *hint = m_client->getBlackboxHint();
Atom atom_return; if (!hint) return;
unsigned long num, len;
FbAtoms *atoms = FbAtoms::instance();
if (XGetWindowProperty(display, m_client->window(), if (hint->flags & ATTRIB_SHADED)
atoms->getFluxboxHintsAtom(), 0, shaded = (hint->attrib & ATTRIB_SHADED);
PropBlackboxHintsElements, False,
atoms->getFluxboxHintsAtom(), &atom_return,
&format, &num, &len,
(unsigned char **) &m_client->blackbox_hint) == Success &&
m_client->blackbox_hint) {
if (num == (unsigned)PropBlackboxHintsElements) { if ((hint->flags & ATTRIB_MAXHORIZ) &&
if (m_client->blackbox_hint->flags & ATTRIB_SHADED) (hint->flags & ATTRIB_MAXVERT))
shaded = (m_client->blackbox_hint->attrib & ATTRIB_SHADED); maximized = ((hint->attrib &
if ((m_client->blackbox_hint->flags & ATTRIB_MAXHORIZ) &&
(m_client->blackbox_hint->flags & ATTRIB_MAXVERT))
maximized = ((m_client->blackbox_hint->attrib &
(ATTRIB_MAXHORIZ | (ATTRIB_MAXHORIZ |
ATTRIB_MAXVERT)) ? 1 : 0); ATTRIB_MAXVERT)) ? 1 : 0);
else if (m_client->blackbox_hint->flags & ATTRIB_MAXVERT) else if (hint->flags & ATTRIB_MAXVERT)
maximized = ((m_client->blackbox_hint->attrib & maximized = ((hint->attrib &
ATTRIB_MAXVERT) ? 2 : 0); ATTRIB_MAXVERT) ? 2 : 0);
else if (m_client->blackbox_hint->flags & ATTRIB_MAXHORIZ) else if (hint->flags & ATTRIB_MAXHORIZ)
maximized = ((m_client->blackbox_hint->attrib & maximized = ((hint->attrib &
ATTRIB_MAXHORIZ) ? 3 : 0); ATTRIB_MAXHORIZ) ? 3 : 0);
if (m_client->blackbox_hint->flags & ATTRIB_OMNIPRESENT) if (hint->flags & ATTRIB_OMNIPRESENT)
stuck = (m_client->blackbox_hint->attrib & stuck = (hint->attrib &
ATTRIB_OMNIPRESENT); ATTRIB_OMNIPRESENT);
if (m_client->blackbox_hint->flags & ATTRIB_WORKSPACE) if (hint->flags & ATTRIB_WORKSPACE)
m_workspace_number = m_client->blackbox_hint->workspace; m_workspace_number = hint->workspace;
if (m_client->blackbox_hint->flags & ATTRIB_STACK) if (hint->flags & ATTRIB_STACK)
m_workspace_number = m_client->blackbox_hint->stack; m_workspace_number = hint->stack;
if (m_client->blackbox_hint->flags & ATTRIB_DECORATION) { if (hint->flags & ATTRIB_DECORATION) {
m_old_decoration = static_cast<Decoration>(m_client->blackbox_hint->decoration); m_old_decoration = static_cast<Decoration>(hint->decoration);
setDecoration(m_old_decoration); setDecoration(m_old_decoration);
} }
} }
}
}
void FluxboxWindow::move(int x, int y) { void FluxboxWindow::move(int x, int y) {
moveResize(x, y, frame().width(), frame().height()); moveResize(x, y, frame().width(), frame().height());
@ -1201,7 +1066,7 @@ bool FluxboxWindow::setInputFocus() {
return (*it)->fbwindow()->setCurrentClient(**it, true); return (*it)->fbwindow()->setCurrentClient(**it, true);
} }
} else { } else {
if (m_focus_mode == F_LOCALLYACTIVE || m_focus_mode == F_PASSIVE) { if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || m_client->getFocusMode() == WinClient::F_PASSIVE) {
XSetInputFocus(display, m_client->window(), XSetInputFocus(display, m_client->window(),
RevertToPointerRoot, CurrentTime); RevertToPointerRoot, CurrentTime);
} else { } else {
@ -1214,7 +1079,6 @@ bool FluxboxWindow::setInputFocus() {
frame().setFocus(true); frame().setFocus(true);
if (send_focus_message)
m_client->sendFocus(); m_client->sendFocus();
if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus())
@ -1428,7 +1292,7 @@ void FluxboxWindow::setLayerNum(int layernum) {
m_blackbox_attrib.flags |= ATTRIB_STACK; m_blackbox_attrib.flags |= ATTRIB_STACK;
m_blackbox_attrib.stack = layernum; m_blackbox_attrib.stack = layernum;
saveBlackboxHints(); saveBlackboxAttribs();
#ifdef DEBUG #ifdef DEBUG
cerr<<this<<" notify layer signal"<<endl; cerr<<this<<" notify layer signal"<<endl;
@ -1688,14 +1552,18 @@ void FluxboxWindow::installColormap(bool install) {
} }
/** /**
Saves blackbox hints for every client in our list Saves blackbox attributes for every client in our list
*/ */
void FluxboxWindow::saveBlackboxHints() { void FluxboxWindow::saveBlackboxAttribs() {
for_each(m_clientlist.begin(), m_clientlist.end(), for_each(m_clientlist.begin(), m_clientlist.end(),
FbTk::ChangeProperty(display, FbAtoms::instance()->getFluxboxAttributesAtom(), FbTk::ChangeProperty(
display,
FbAtoms::instance()->getFluxboxAttributesAtom(),
PropModeReplace, PropModeReplace,
(unsigned char *)&m_blackbox_attrib, (unsigned char *)&m_blackbox_attrib,
PropBlackboxAttributesElements)); PropBlackboxAttributesElements
)
);
} }
/** /**
@ -1715,7 +1583,7 @@ void FluxboxWindow::setState(unsigned long new_state) {
PropModeReplace, PropModeReplace,
(unsigned char *)state, 2)); (unsigned char *)state, 2));
saveBlackboxHints(); saveBlackboxAttribs();
//notify state changed //notify state changed
m_statesig.notify(); m_statesig.notify();
} }
@ -1833,7 +1701,11 @@ void FluxboxWindow::restoreAttributes() {
PropBlackboxAttributesElements, false, PropBlackboxAttributesElements, false,
fbatoms->getFluxboxAttributesAtom(), &atom_return, &foo, fbatoms->getFluxboxAttributesAtom(), &atom_return, &foo,
&nitems, &ulfoo, (unsigned char **) &net) && &nitems, &ulfoo, (unsigned char **) &net) &&
net && nitems == (unsigned)PropBlackboxAttributesElements) { net) {
if (nitems != (unsigned)PropBlackboxAttributesElements) {
XFree(net);
return;
}
m_blackbox_attrib.flags = net->flags; m_blackbox_attrib.flags = net->flags;
m_blackbox_attrib.attrib = net->attrib; m_blackbox_attrib.attrib = net->attrib;
m_blackbox_attrib.workspace = net->workspace; m_blackbox_attrib.workspace = net->workspace;
@ -2179,7 +2051,7 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
} break; } break;
case XA_WM_HINTS: case XA_WM_HINTS:
getWMHints(); m_client->updateWMHints();
break; break;
case XA_WM_ICON_NAME: case XA_WM_ICON_NAME:
@ -2199,7 +2071,7 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
break; break;
case XA_WM_NORMAL_HINTS: { case XA_WM_NORMAL_HINTS: {
getWMNormalHints(); m_client->updateWMNormalHints();
if ((m_client->normal_hint_flags & PMinSize) && if ((m_client->normal_hint_flags & PMinSize) &&
(m_client->normal_hint_flags & PMaxSize)) { (m_client->normal_hint_flags & PMaxSize)) {

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// $Id: Window.hh,v 1.79 2003/06/18 13:55:16 fluxgen Exp $ // $Id: Window.hh,v 1.80 2003/06/23 14:16:05 rathnor Exp $
#ifndef WINDOW_HH #ifndef WINDOW_HH
#define WINDOW_HH #define WINDOW_HH
@ -103,10 +103,6 @@ public:
ATTRIB_DECORATION = 0x40 ATTRIB_DECORATION = 0x40
}; };
static const int PropBlackboxHintsElements = 5;
static const int PropBlackboxAttributesElements = 8;
static const int PropMwmHintsElements = 3;
typedef struct _blackbox_hints { typedef struct _blackbox_hints {
unsigned long flags, attrib, workspace, stack; unsigned long flags, attrib, workspace, stack;
int decoration; int decoration;
@ -126,11 +122,6 @@ public:
FbTk::MenuTheme &menutheme, FbTk::MenuTheme &menutheme,
FbTk::XLayer &layer); FbTk::XLayer &layer);
/// create fluxbox window with parent win and screen connection
FluxboxWindow(Window win, BScreen &scr,
FbWinFrameTheme &tm,
FbTk::MenuTheme &menutheme,
FbTk::XLayer &layer);
virtual ~FluxboxWindow(); virtual ~FluxboxWindow();
/// attach client to our client list and remove it from old window /// attach client to our client list and remove it from old window
@ -348,6 +339,8 @@ public:
// during certain operations // during certain operations
private: private:
static const int PropBlackboxAttributesElements = 8;
void init(); void init();
/// applies a shape mask to the window if it has one /// applies a shape mask to the window if it has one
void shape(); void shape();
@ -367,12 +360,10 @@ private:
void updateTitleFromClient(); void updateTitleFromClient();
/// gets icon name from client window /// gets icon name from client window
void updateIconNameFromClient(); void updateIconNameFromClient();
void getWMNormalHints();
void getWMProtocols(); void getWMProtocols();
void getWMHints();
void getMWMHints(); void getMWMHints();
void getBlackboxHints(); void getBlackboxHints();
void saveBlackboxHints(); void saveBlackboxAttribs();
void setNetWMAttributes(); void setNetWMAttributes();
void associateClientWindow(); void associateClientWindow();
@ -394,7 +385,7 @@ private:
// Window states // Window states
bool moving, resizing, shaded, maximized, iconic, bool moving, resizing, shaded, maximized, iconic,
focused, stuck, send_focus_message, m_managed; focused, stuck, m_managed;
WinClient *m_attaching_tab; WinClient *m_attaching_tab;
@ -414,7 +405,7 @@ private:
int m_last_move_x, m_last_move_y; // handles last pos for non opaque moving int m_last_move_x, m_last_move_y; // handles last pos for non opaque moving
unsigned int m_last_resize_h, m_last_resize_w; // handles height/width for resize "window" unsigned int m_last_resize_h, m_last_resize_w; // handles height/width for resize "window"
int m_focus_mode, m_window_number; int m_window_number;
unsigned int m_workspace_number; unsigned int m_workspace_number;
unsigned long m_current_state; unsigned long m_current_state;
@ -452,8 +443,6 @@ private:
FbTk::FbWindow &m_parent; ///< window on which we draw move/resize rectangle (the "root window") FbTk::FbWindow &m_parent; ///< window on which we draw move/resize rectangle (the "root window")
enum { F_NOINPUT = 0, F_PASSIVE, F_LOCALLYACTIVE, F_GLOBALLYACTIVE };
}; };