all repos — fluxbox @ 7e4f8a38531642cc9cb6cba31499d549f4c5f8a0

custom fork of the fluxbox windowmanager

add support for transient windows in client patterns, and merge a few more changes from pre-devel
markt markt
commit

7e4f8a38531642cc9cb6cba31499d549f4c5f8a0

parent

79cd21ce0fe56f4b38a96ecccc969f740b801cc8

M ChangeLogChangeLog

@@ -1,6 +1,9 @@

(Format: Year/Month/Day) Changes for 1.0.1: *07/10/14: + * Added support for transient windows in window patterns, e.g. + (transient=yes|no), defaulting to "no" for the apps file (Mark) + Remember.cc ClientPattern.cc/hh Focusable.hh Window.cc/hh * Bugfix for SendToPrevWorkspace/TakeToPrevWorkspace (Mathias) CurrentWindowCmd.cc/hh *07/10/13:
M data/init.indata/init.in

@@ -31,4 +31,4 @@ session.colorsPerChannel: 4

session.doubleClickInterval: 250 session.cacheMax: 200 session.imageDither: True -session.configVersion: 1 +session.configVersion: 3
M data/keysdata/keys

@@ -4,6 +4,9 @@ OnDesktop Mouse3 :RootMenu

OnDesktop Mouse4 :NextWorkspace OnDesktop Mouse5 :PrevWorkspace +OnToolbar Mouse4 :NextWorkspace +OnToolbar Mouse5 :PrevWorkspace + Mod1 Tab :NextWindow Mod1 Shift Tab :PrevWindow Mod1 F1 :Workspace 1
M doc/asciidoc/fluxbox.txtdoc/asciidoc/fluxbox.txt

@@ -706,20 +706,15 @@ and slit. This behavior can be that they disappear when they are not being

used actively by the user, or they remain visible at all times. Default: False -session.screen0.desktopwheeling: <boolean> - This sets the ability to utilize the user's scroll wheel to change the - current workspace. Default: True - session.screen0.windowScrollAction: shade|nexttab This allows you to execute a command by scrolling on the titlebar of a window. For `shade', scrolling down will shade the window, and scrolling up will unshade it. For `nexttab', scrolling down will focus the next tab, and scrolling up will focus the previous one. Default: <blank> -session.screen0.reversewheeling: <boolean> session.screen0.windowScrollReverse: <boolean> - These switch the roles of scrolling up and scrolling down for the previous - two sets of resources. Default: False + This switches the role of scrolling up and scrolling down for the previous + resource. Default: False session.screen0.slit.layer: <layer> session.screen0.toolbar.layer: <layer>

@@ -802,12 +797,6 @@ session.screen0.iconbar.iconTextPadding: <integer>

This specifies the space between the window title and the edge of the button. Default: 10 -session.screen0.iconbar.wheelMode: Screen|On|Off - This defines the behavior for scrolling on the iconbar. `Screen' uses the - value set in session.screen0.desktopWheeling . `On' means scrolling on the - iconbar will change the current workspace. `Off' means scrolling on the - iconbar will do nothing. Default: Screen - session.screen0.iconbar.alignment: <position> This value should be changed in the Iconbar Mode menu. Default: Relative

@@ -847,16 +836,17 @@

session.screen0.tab.width: <integer> This specifies the width of external tabs in pixels. Default: 64 -session.screen0.followModel: <model> session.screen0.userFollowModel: <model> This specifies the behavior when a window on another workspace becomes the - active window. The former is used when an application asks to focus the - window, and the latter is used when the window is activated due to user - actions, such as clicking in the iconbar, menu, or a pager. `Ignore' does - nothing. `Follow' moves to the window's workspace. `Current' moves the - window to the current workspace. `SemiFollow' acts like `Current' for - iconified windows and like `Follow' otherwise. Defaults: Ignore and - Follow, respectively. + active window. `Ignore' does nothing. `Follow' moves to the window's + workspace. `Current' moves the window to the current workspace. + `SemiFollow' acts like `Current' for minimized windows and like `Follow' + otherwise. Default: Follow + +session.screen0.followModel: <model> + This specifies the behavior when a window on another workspace requests to + be focused. `Ignore' does nothing, and `Follow' uses the setting in + session.screen0.userFollowModel. Default: Ignore session.screen0.resizeMode: Bottom|Quadrant|Center Setting this resource to `Quadrant' makes resizing by using the modkey
M src/ClientPattern.ccsrc/ClientPattern.cc

@@ -60,7 +60,7 @@ m_matchlimit(0),

m_nummatches(0) {} // parse the given pattern (to end of line) -ClientPattern::ClientPattern(const char *str): +ClientPattern::ClientPattern(const char *str, bool default_no_transient): m_matchlimit(0), m_nummatches(0) {

@@ -107,6 +107,9 @@ } else if (strcasecmp(memstr.c_str(), "title") == 0) {

prop = TITLE; } else if (strcasecmp(memstr.c_str(), "role") == 0) { prop = ROLE; + } else if (strcasecmp(memstr.c_str(), "transient") == 0) { + prop = TRANSIENT; + default_no_transient = false; } else if (strcasecmp(memstr.c_str(), "maximized") == 0) { prop = MAXIMIZED; } else if (strcasecmp(memstr.c_str(), "minimized") == 0) {

@@ -138,6 +141,9 @@ // no match terms given, this is not allowed

had_error = true; } + if (default_no_transient) + had_error = !addTerm("no", TRANSIENT); + if (!had_error) { // otherwise, we check for a number string number;

@@ -200,6 +206,9 @@ pat.append("title=");

break; case ROLE: pat.append("role="); + break; + case TRANSIENT: + pat.append("transient="); break; case MAXIMIZED: pat.append("maximized=");

@@ -306,6 +315,9 @@ return client.getWMClassName();

break; case ROLE: return client.getWMRole(); + break; + case TRANSIENT: + return client.isTransient() ? "yes" : "no"; break; case MAXIMIZED: return (fbwin && fbwin->isMaximized()) ? "yes" : "no";
M src/ClientPattern.hhsrc/ClientPattern.hh

@@ -46,7 +46,7 @@ * Create the pattern from the given string as it would appear in the

* apps file. the bool value returns the character at which * there was a parse problem, or -1. */ - explicit ClientPattern(const char * str); + explicit ClientPattern(const char * str, bool default_no_transient = false); ~ClientPattern();

@@ -54,7 +54,7 @@ /// @return a string representation of this pattern

std::string toString() const; enum WinProperty { - TITLE, CLASS, NAME, ROLE, + TITLE, CLASS, NAME, ROLE, TRANSIENT, MAXIMIZED, MINIMIZED, SHADED, STUCK, FOCUSHIDDEN, ICONHIDDEN, WORKSPACE, HEAD, LAYER };
M src/Focusable.hhsrc/Focusable.hh

@@ -84,8 +84,11 @@ /// @return WM_CLASS class string (for pattern matching)

virtual const std::string &getWMClassClass() const { return m_class_name; } /// @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) + /// @return wm role string (for pattern matching) virtual std::string getWMRole() const { return "Focusable"; } + + /// @return whether this window is a transient (for pattern matching) + virtual bool isTransient() const { return false; } // so we can make nice buttons, menu entries, etc. /// @return icon pixmap of the focusable
M src/Remember.ccsrc/Remember.cc

@@ -339,6 +339,7 @@ p->addTerm(win_name, ClientPattern::NAME);

p->addTerm(win_class, ClientPattern::CLASS); if (!win_role.empty()) p->addTerm(win_role, ClientPattern::ROLE); + p->addTerm(winclient.isTransient() ? "yes" : "no", ClientPattern::TRANSIENT); m_clients[&winclient] = app; p->addMatch(); m_pats->push_back(make_pair(p, app));

@@ -594,7 +595,7 @@ line.c_str(),

'[', ']'); if (pos > 0 && strcasecmp(key.c_str(), "app") == 0) { - ClientPattern *pat = new ClientPattern(line.c_str() + pos); + ClientPattern *pat = new ClientPattern(line.c_str() + pos, true); if (!in_group) { if ((err = pat->error()) == 0) { Application *app = findMatchingPatterns(pat, old_pats, false);

@@ -620,7 +621,7 @@ m_startups.push_back(line.substr(pos));

} else if (pos > 0 && strcasecmp(key.c_str(), "group") == 0) { in_group = true; if (line.find('(') != string::npos) - pat = new ClientPattern(line.c_str() + pos); + pat = new ClientPattern(line.c_str() + pos, true); } else if (in_group) { // otherwise assume that it is the start of the attributes Application *app = 0;

@@ -1020,13 +1021,6 @@ }

void Remember::setupFrame(FluxboxWindow &win) { WinClient &winclient = win.winClient(); - // we don't touch the window if it is a transient - // of something else - - - if (winclient.transientFor()) - return; - Application *app = find(winclient); if (app == 0) return; // nothing to do

@@ -1123,8 +1117,7 @@

void Remember::setupClient(WinClient &winclient) { // leave windows alone on restart - // don't apply settings to transient windows - if (winclient.screen().isRestart() || winclient.transientFor()) + if (winclient.screen().isRestart()) return; Application *app = find(winclient);
M src/Window.ccsrc/Window.cc

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

return (m_client ? m_client->getWMRole() : "FluxboxWindow"); } +bool FluxboxWindow::isTransient() const { + return (m_client && m_client->isTransient()); +} + int FluxboxWindow::normalX() const { if (maximized & MAX_HORZ) return m_old_pos_x;
M src/Window.hhsrc/Window.hh

@@ -435,6 +435,7 @@ const std::string &title() const;

const std::string &getWMClassName() const; const std::string &getWMClassClass() const; std::string getWMRole() const; + bool isTransient() const; inline int x() const { return frame().x(); } inline int y() const { return frame().y(); }