all repos — fluxbox @ 97f7c3e1b59b9a94e36a78d97c141f6a05f43e20

custom fork of the fluxbox windowmanager

various refactoring and minor changes
markt markt
commit

97f7c3e1b59b9a94e36a78d97c141f6a05f43e20

parent

2c4e1f9a024433396f17ea5f3ef3fda46e0d8edd

M src/Ewmh.ccsrc/Ewmh.cc

@@ -214,19 +214,9 @@ void Ewmh::setupClient(WinClient &winclient) {

updateStrut(winclient); FbTk::FbString newtitle = winclient.textProperty(m_net_wm_name); - if (!newtitle.empty()) { + if (!newtitle.empty()) winclient.setTitle(newtitle); - } - newtitle = winclient.textProperty(m_net_wm_icon_name); - if (!newtitle.empty()) { - winclient.setIconTitle(newtitle); - } - if ( winclient.fbwindow() ) - winclient.fbwindow()->titleSig().notify(); -} - -void Ewmh::setupFrame(FluxboxWindow &win) { Atom ret_type; int fmt; unsigned long nitems, bytes_after;

@@ -248,94 +238,58 @@ * Managers that do not recognize the extensions.

* */ - win.winClient().property(m_net_wm_window_type, 0, 0x7fffffff, False, XA_ATOM, - &ret_type, &fmt, &nitems, &bytes_after, - &data); + winclient.property(m_net_wm_window_type, 0, 0x7fffffff, False, XA_ATOM, + &ret_type, &fmt, &nitems, &bytes_after, + &data); + Focusable::WindowType type = Focusable::TYPE_NORMAL; if (data) { Atom *atoms = (unsigned long *)data; for (unsigned long l = 0; l < nitems; ++l) { - /* From Extended Window Manager Hints, draft 1.3: - * - * _NET_WM_WINDOW_TYPE_DOCK indicates a dock or panel feature. - * Typically a Window Manager would keep such windows on top - * of all other windows. - * + if (atoms[l] == m_net_wm_window_type_dock) + type = Focusable::TYPE_DOCK; + else if (atoms[l] == m_net_wm_window_type_desktop) + type = Focusable::TYPE_DESKTOP; + else if (atoms[l] == m_net_wm_window_type_splash) + type = Focusable::TYPE_SPLASH; + else if (atoms[l] == m_net_wm_window_type_dialog) + type = Focusable::TYPE_DIALOG; + else if (atoms[l] == m_net_wm_window_type_menu) + type = Focusable::TYPE_MENU; + else if (atoms[l] == m_net_wm_window_type_toolbar) + type = Focusable::TYPE_TOOLBAR; + else if (atoms[l] != m_net_wm_window_type_normal) + continue; + /* + * NOT YET IMPLEMENTED: + * _NET_WM_WINDOW_TYPE_UTILITY */ - if (atoms[l] == m_net_wm_window_type_dock) { - // we also assume it shouldn't be visible in any toolbar - win.setFocusHidden(true); - win.setIconHidden(true); - win.setDecorationMask(FluxboxWindow::DECOR_NONE); - win.moveToLayer(Layer::DOCK); - } else if (atoms[l] == m_net_wm_window_type_desktop) { - /* - * _NET_WM_WINDOW_TYPE_DESKTOP indicates a "false desktop" window - * We let it be the size it wants, but it gets no decoration, - * is hidden in the toolbar and window cycling list, plus - * windows don't tab with it and is right on the bottom. - */ - - win.setFocusHidden(true); - win.setIconHidden(true); - win.moveToLayer(Layer::DESKTOP); - win.setDecorationMask(FluxboxWindow::DECOR_NONE); - win.setTabable(false); - win.setMovable(false); - win.setResizable(false); - win.stick(); - - } else if (atoms[l] == m_net_wm_window_type_splash) { - /* - * _NET_WM_WINDOW_TYPE_SPLASH indicates that the - * window is a splash screen displayed as an application - * is starting up. - */ - win.setDecorationMask(FluxboxWindow::DECOR_NONE); - win.setFocusHidden(true); - win.setIconHidden(true); - win.setMovable(false); - } else if (atoms[l] == m_net_wm_window_type_normal) { - // do nothing, this is ..normal.. - } else if (atoms[l] == m_net_wm_window_type_dialog) { - // dialog windows should not be tabable - win.setTabable(false); - } else if (atoms[l] == m_net_wm_window_type_menu) { - /* - * _NET_WM_WINDOW_TYPE_TOOLBAR and _NET_WM_WINDOW_TYPE_MENU - * indicate toolbar and pinnable menu windows, respectively - * (i.e. toolbars and menus "torn off" from the main - * application). Windows of this type may set the - * WM_TRANSIENT_FOR hint indicating the main application window. - */ - win.setDecorationMask(FluxboxWindow::DECOR_TOOL); - win.setIconHidden(true); - win.moveToLayer(Layer::ABOVE_DOCK); - } else if (atoms[l] == m_net_wm_window_type_toolbar) { - win.setDecorationMask(FluxboxWindow::DECOR_NONE); - win.setIconHidden(true); - win.moveToLayer(Layer::ABOVE_DOCK); - } + break; } XFree(data); - } else { + } else if (winclient.isTransient()) { // if _NET_WM_WINDOW_TYPE not set and this window // has transient_for the type must be set to _NET_WM_WINDOW_TYPE_DIALOG - if ( win.winClient().isTransient() ) { - win.winClient(). + if (winclient.isTransient()) { + type = Focusable::TYPE_DIALOG; + winclient. changeProperty(m_net_wm_window_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&m_net_wm_window_type_dialog, 1); - // and then we should treat it like a dialog - win.setTabable(false); + } } + winclient.setWindowType(type); - /* - * NOT YET IMPLEMENTED: - * _NET_WM_WINDOW_TYPE_UTILITY - */ + +} +void Ewmh::setupFrame(FluxboxWindow &win) { setupState(win); + + Atom ret_type; + int fmt; + unsigned long nitems, bytes_after; + unsigned char *data = 0; if (win.winClient().property(m_net_wm_desktop, 0, 1, False, XA_CARDINAL, &ret_type, &fmt, &nitems, &bytes_after,

@@ -929,11 +883,7 @@ if (winclient.fbwindow())

winclient.fbwindow()->titleSig().notify(); return true; } else if (the_property == m_net_wm_icon_name) { - FbTk::FbString newtitle = winclient.textProperty(the_property); - if (!newtitle.empty()) - winclient.setIconTitle(newtitle); - if (winclient.fbwindow()) - winclient.fbwindow()->titleSig().notify(); + // we don't use icon title, since we don't show icons return true; }
M src/FocusControl.ccsrc/FocusControl.cc

@@ -167,32 +167,17 @@ }

void FocusControl::goToWindowNumber(const Focusables &winlist, int num, const ClientPattern *pat) { - Focusable *last_matched = 0; - if (num > 0) { - Focusables::const_iterator it = winlist.begin(); - Focusables::const_iterator it_end = winlist.end(); - for (; it != it_end; ++it) { - if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { - --num; - last_matched = *it; - if (!num) break; + Focusables::const_iterator it = winlist.begin(); + Focusables::const_iterator it_end = winlist.end(); + for (; it != it_end && num; ++it) { + if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { + num > 0 ? --num : ++num; + if (!num) { + (*it)->focus(); + if ((*it)->fbwindow()) + (*it)->fbwindow()->raise(); } } - } else if (num < 0) { - Focusables::const_reverse_iterator it = winlist.rbegin(); - Focusables::const_reverse_iterator it_end = winlist.rend(); - for (; it != it_end; ++it) { - if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { - ++num; - last_matched = *it; - if (!num) break; - } - } - } - if (last_matched) { - last_matched->focus(); - if (last_matched->fbwindow()) - last_matched->fbwindow()->raise(); } }

@@ -371,7 +356,7 @@ for (; it != wins.end(); ++it) {

if ((*it) == &win || (*it)->isIconic() || (*it)->isFocusHidden() - || !(*it)->winClient().acceptsFocus()) + || !(*it)->acceptsFocus()) continue; // skip self // we check things against an edge, and within the bounds (draw a picture)
M src/Focusable.hhsrc/Focusable.hh

@@ -46,6 +46,17 @@ m_focused(false), m_attention_state(false),

m_titlesig(*this), m_focussig(*this), m_diesig(*this), m_attentionsig(*this) { } virtual ~Focusable() { } + + enum WindowType { + TYPE_NORMAL, + TYPE_DOCK, + TYPE_DESKTOP, + TYPE_SPLASH, + TYPE_DIALOG, + TYPE_MENU, + TYPE_TOOLBAR + }; + /** * Take focus. * @return true if the focuable took focus

@@ -86,6 +97,9 @@ /// @return WM_CLASS name string (for pattern matching)

virtual const std::string &getWMClassName() const { return m_instance_name; } /// @return wm role string (for pattern matching) virtual std::string getWMRole() const { return "Focusable"; } + + /// @return window type + virtual WindowType getWindowType() const { return TYPE_NORMAL; } /// @return whether this window is a transient (for pattern matching) virtual bool isTransient() const { return false; }
M src/Keys.ccsrc/Keys.cc

@@ -390,6 +390,11 @@

// grab "None Escape" to exit keychain in the middle unsigned int esc = FbTk::KeyUtil::getKey("Escape"); + // if focus changes, windows will get NotifyWhileGrabbed, + // which they tend to ignore + if (temp_key && type == KeyPress) + XUngrabKeyboard(Fluxbox::instance()->display(), CurrentTime); + if (temp_key && !temp_key->keylist.empty()) { // emacs-style if (!saved_keymode) saved_keymode = m_keylist;
M src/WinClient.ccsrc/WinClient.cc

@@ -79,13 +79,13 @@ normal_hint_flags(0),

wm_hint_flags(0), m_modal_count(0), m_modal(false), + accepts_input(false), send_focus_message(false), send_close_message(false), m_win_gravity(0), m_title_override(false), - m_icon_title_override(false), + m_window_type(Focusable::TYPE_NORMAL), m_mwm_hint(0), - m_focus_mode(F_PASSIVE), m_strut(0) { updateWMProtocols(); updateMWMHints();

@@ -93,7 +93,6 @@ updateWMHints();

updateWMNormalHints(); updateWMClassHint(); updateTitle(); - updateIconTitle(); Fluxbox::instance()->saveWindowSearch(win, this); if (window_group != None) Fluxbox::instance()->saveGroupSearch(window_group, this);

@@ -167,11 +166,17 @@ fluxbox->removeWindowSearch(window());

} bool WinClient::acceptsFocus() const { - return (m_focus_mode == F_LOCALLYACTIVE || - m_focus_mode == F_PASSIVE); + return ((accepts_input || send_focus_message) && + // focusing fbpanel messes up quite a few things + m_window_type != Focusable::TYPE_DOCK && + m_window_type != Focusable::TYPE_SPLASH); } bool WinClient::sendFocus() { + if (accepts_input) { + setInputFocus(RevertToParent, CurrentTime); + return true; + } if (!send_focus_message) return false; #ifdef DEBUG

@@ -234,12 +239,6 @@ string WinClient::getWMRole() const {

Atom wm_role = XInternAtom(FbTk::App::instance()->display(), "WM_WINDOW_ROLE", False); return textProperty(wm_role); -} - -const string &WinClient::title() const { - if (!fbwindow() || !fbwindow()->isIconic() || m_icon_title.empty()) - return m_title; - return m_icon_title; } void WinClient::updateWMClassHint() {

@@ -369,48 +368,6 @@ if (fbwindow())

fbwindow()->updateTitleFromClient(*this); } -void WinClient::setIconTitle(FbTk::FbString &icon_title) { - m_icon_title = icon_title; - m_icon_title_override = true; - if (fbwindow() && fbwindow()->isIconic()) - fbwindow()->updateTitleFromClient(*this); -} - -void WinClient::updateIconTitle() { - if (m_icon_title_override) - return; - - XTextProperty text_prop; - char **list = 0; - int num = 0; - - if (getWMIconName(text_prop)) { - if (text_prop.value && text_prop.nitems > 0) { - if (text_prop.encoding != XA_STRING) { - text_prop.nitems = strlen((char *) text_prop.value); - XmbTextPropertyToTextList(display(), &text_prop, &list, &num); - - if (num > 0 && list) - m_icon_title = (char *)*list; - else - m_icon_title = text_prop.value ? (char *)text_prop.value : ""; - if (list) - XFreeStringList(list); - - } else - m_icon_title = text_prop.value ? (char *)text_prop.value : ""; - - if (text_prop.value) - XFree((char *) text_prop.value); - } else - m_icon_title = ""; - } else - m_icon_title = ""; - - if (fbwindow() && fbwindow()->isIconic()) - fbwindow()->updateTitleFromClient(*this); -} - void WinClient::saveBlackboxAttribs(FluxboxWindow::BlackboxAttributes &blackbox_attribs) { changeProperty(FbAtoms::instance()->getFluxboxAttributesAtom(), XA_CARDINAL, 32, PropModeReplace,

@@ -450,11 +407,10 @@ }

void WinClient::updateWMHints() { XWMHints *wmhint = XGetWMHints(display(), window()); - if (! wmhint) { - m_focus_mode = F_PASSIVE; - window_group = None; - initial_state = NormalState; - } else { + accepts_input = true; + window_group = None; + initial_state = NormalState; + if (wmhint) { wm_hint_flags = wmhint->flags; /* * ICCCM 4.1.7

@@ -467,34 +423,16 @@ * Locally Active True Present

* Globally Active False Present *--------------------------------------------- * Here: WM_TAKE_FOCUS = send_focus_message - * Input Field = wmhint->input - * Input Model = m_focus_mode + * Input Field = accepts_input */ - 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 // InputHint not present: ignoring send_focus_message and assuming F_PASSIVE - m_focus_mode = F_PASSIVE; + if (wmhint->flags & InputHint) + accepts_input = (bool)wmhint->input; 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; + if (wmhint->flags & WindowGroupHint && !window_group) + window_group = wmhint->window_group; if ((bool)(wmhint->flags & IconPixmapHint) && wmhint->icon_pixmap != 0) m_icon.pixmap().copy(wmhint->icon_pixmap, 0, 0);
M src/WinClient.hhsrc/WinClient.hh

@@ -64,9 +64,7 @@ void updateWMProtocols();

// override the title with this void setTitle(FbTk::FbString &title); - void setIconTitle(FbTk::FbString &icon_title); void updateTitle(); - void updateIconTitle(); /// updates transient window information void updateTransientInfo();

@@ -80,7 +78,7 @@

bool focus(); // calls Window->setCurrentClient to give focus to this client bool isFocused() const; void setAttentionState(bool value); - const std::string &title() const; + const std::string &title() const { return m_title; } /** * Changes width and height to the nearest (lower) value

@@ -110,6 +108,8 @@ bool getAttrib(XWindowAttributes &attr) const;

bool getWMName(XTextProperty &textprop) const; bool getWMIconName(XTextProperty &textprop) const; std::string getWMRole() const; + Focusable::WindowType getWindowType() const { return m_window_type; } + void setWindowType(Focusable::WindowType type) { m_window_type = type; } inline WinClient *transientFor() { return transient_for; } inline const WinClient *transientFor() const { return transient_for; }

@@ -127,7 +127,6 @@ bool hasGroupLeftWindow() const;

// grouping is tracked by remembering the window to the left in the group Window getGroupLeftWindow() const; - inline int getFocusMode() const { return m_focus_mode; } inline const MwmHints *getMwmHint() const { return m_mwm_hint; } inline unsigned int maxWidth() const { return max_width; }

@@ -152,9 +151,6 @@ min_aspect_x, min_aspect_y, max_aspect_x, max_aspect_y,

base_width, base_height; unsigned long initial_state, normal_hint_flags, wm_hint_flags; - - enum FocusMode { F_NOINPUT = 0, F_PASSIVE, F_LOCALLYACTIVE, F_GLOBALLYACTIVE }; - private: /// removes client from any waiting list and clears empty waiting lists void removeTransientFromWaitingList();

@@ -167,16 +163,14 @@

// number of transients which we are modal for int m_modal_count; bool m_modal; - bool send_focus_message, send_close_message; + bool accepts_input, send_focus_message, send_close_message; int m_win_gravity; - std::string m_icon_title; - bool m_title_override, m_icon_title_override; + bool m_title_override; + Focusable::WindowType m_window_type; MwmHints *m_mwm_hint; - - int m_focus_mode; Strut *m_strut; // map transient_for X window to winclient transient
M src/Window.ccsrc/Window.cc

@@ -453,6 +453,8 @@ wattrib.x, wattrib.y,

wattrib.width, wattrib.height, m_client->gravity(), m_client->old_bw); + setWindowType(m_client->getWindowType()); + if (fluxbox.isStartup()) m_placed = true; else if (m_client->isTransient() ||

@@ -1021,7 +1023,6 @@ int x, int y,

unsigned int width, unsigned int height, int gravity, unsigned int client_bw) { m_client->updateTitle(); - m_client->updateIconTitle(); frame().setShapingClient(m_client, false);

@@ -1353,26 +1354,7 @@

if (m_client->isModal()) return false; - bool ret = false; - - if (m_client->acceptsFocus()) { - - m_client->setInputFocus(RevertToParent, CurrentTime); - - FbTk::App *app = FbTk::App::instance(); - - XFlush(app->display()); - - m_client->sendFocus(); - - app->sync(false); - - ret = true; - } else { - ret = m_client->sendFocus(); - } - - return ret; + return m_client->sendFocus(); } // don't hide the frame directly, use this function

@@ -2129,14 +2111,6 @@ //!! TODO check value?

m_layernum = m_blackbox_attrib.stack; } - if ((m_blackbox_attrib.flags & ATTRIB_MAXHORIZ) || - (m_blackbox_attrib.flags & ATTRIB_MAXVERT)) { - m_blackbox_attrib.premax_x = m_blackbox_attrib.premax_x; - m_blackbox_attrib.premax_y = m_blackbox_attrib.premax_y; - m_blackbox_attrib.premax_w = m_blackbox_attrib.premax_w; - m_blackbox_attrib.premax_h = m_blackbox_attrib.premax_h; - } - } /**

@@ -2369,8 +2343,9 @@ // hintSig().notify(); // notify listeners

break; case XA_WM_ICON_NAME: - // update icon title and then do normal XA_WM_NAME stuff - client.updateIconTitle(); + // we don't use icon title, since many apps don't update it, + // and we don't show icons anyway + break; case XA_WM_NAME: client.updateTitle(); break;

@@ -2610,7 +2585,7 @@ // check frame events first

frame().buttonPressEvent(be); if (be.button == 1) { - if (!m_focused) //check focus + if (!m_focused && acceptsFocus()) //check focus focus(); if (frame().window().window() == be.window || frame().tabcontainer().window() == be.window) {

@@ -2968,7 +2943,8 @@ if (ev.window == frame().window() ||

ev.window == m_client->window() || client) { - if (screen().focusControl().isMouseFocus() && !isFocused()) { + if (screen().focusControl().isMouseFocus() && !isFocused() && + acceptsFocus() && getWindowType() != Focusable::TYPE_DESKTOP) { // check that there aren't any subsequent leave notify events in the // X event queue

@@ -3138,7 +3114,6 @@ m_button_grab_x = x - frame().x() - frame().window().borderWidth();

m_button_grab_y = y - frame().y() - frame().window().borderWidth(); moving = true; - maximized = MAX_NONE; Fluxbox *fluxbox = Fluxbox::instance(); // grabbing (and masking) on the root window allows us to

@@ -3674,6 +3649,10 @@ std::string FluxboxWindow::getWMRole() const {

return (m_client ? m_client->getWMRole() : "FluxboxWindow"); } +Focusable::WindowType FluxboxWindow::getWindowType() const { + return (m_client ? m_client->getWindowType() : Focusable::TYPE_NORMAL); +} + bool FluxboxWindow::isTransient() const { return (m_client && m_client->isTransient()); }

@@ -4139,3 +4118,72 @@ // the screen placement strategy is guaranteed to succeed.

screen().placementStrategy().placeWindow(*this, head, place_x, place_y); move(place_x, place_y); } + +void FluxboxWindow::setWindowType(Focusable::WindowType type) { + switch (type) { + case Focusable::TYPE_DOCK: + /* From Extended Window Manager Hints, draft 1.3: + * + * _NET_WM_WINDOW_TYPE_DOCK indicates a dock or panel feature. + * Typically a Window Manager would keep such windows on top + * of all other windows. + * + */ + setFocusHidden(true); + setIconHidden(true); + setDecorationMask(DECOR_NONE); + moveToLayer(::Layer::DOCK); + break; + case Focusable::TYPE_DESKTOP: + /* + * _NET_WM_WINDOW_TYPE_DESKTOP indicates a "false desktop" window + * We let it be the size it wants, but it gets no decoration, + * is hidden in the toolbar and window cycling list, plus + * windows don't tab with it and is right on the bottom. + */ + setFocusHidden(true); + setIconHidden(true); + moveToLayer(::Layer::DESKTOP); + setDecorationMask(DECOR_NONE); + setTabable(false); + setMovable(false); + setResizable(false); + stick(); + break; + case Focusable::TYPE_SPLASH: + /* + * _NET_WM_WINDOW_TYPE_SPLASH indicates that the + * window is a splash screen displayed as an application + * is starting up. + */ + setDecorationMask(DECOR_NONE); + setFocusHidden(true); + setIconHidden(true); + setMovable(false); + break; + case Focusable::TYPE_DIALOG: + setTabable(false); + break; + case Focusable::TYPE_MENU: + case Focusable::TYPE_TOOLBAR: + /* + * _NET_WM_WINDOW_TYPE_TOOLBAR and _NET_WM_WINDOW_TYPE_MENU + * indicate toolbar and pinnable menu windows, respectively + * (i.e. toolbars and menus "torn off" from the main + * application). Windows of this type may set the + * WM_TRANSIENT_FOR hint indicating the main application window. + */ + setDecorationMask(DECOR_TOOL); + setIconHidden(true); + moveToLayer(::Layer::ABOVE_DOCK); + break; + case Focusable::TYPE_NORMAL: + default: + break; + } + + /* + * NOT YET IMPLEMENTED: + * _NET_WM_WINDOW_TYPE_UTILITY + */ +}
M src/Window.hhsrc/Window.hh

@@ -459,6 +459,8 @@ const std::string &title() const;

const std::string &getWMClassName() const; const std::string &getWMClassClass() const; std::string getWMRole() const; + Focusable::WindowType getWindowType() const; + void setWindowType(Focusable::WindowType type); bool isTransient() const; inline int x() const { return frame().x(); }
M src/WorkspaceCmd.ccsrc/WorkspaceCmd.cc

@@ -301,9 +301,12 @@ if (screen == 0)

return; Workspace::Windows windows(screen->currentWorkspace()->windowList()); - std::for_each(windows.begin(), - windows.end(), - std::mem_fun(&FluxboxWindow::iconify)); + Workspace::Windows::iterator it = windows.begin(), + it_end = windows.end(); + for (; it != it_end; ++it) { + if ((*it)->getWindowType() != Focusable::TYPE_DESKTOP) + (*it)->iconify(); + } } void CloseAllWindowsCmd::execute() {