primarily focus fix/tweak/rejigging

This commit is contained in:
rathnor 2004-03-21 09:00:25 +00:00
parent 2d82374b2f
commit dea3281e69
10 changed files with 121 additions and 62 deletions

View file

@ -1,5 +1,12 @@
(Format: Year/Month/Day)
Changes for 0.9.9:
*04/03/21:
* A number of small fixes (Simon)
- Fix up focus+highlights on tab close
- Centralise focus fallbacks (fluxbox::unfocusWindow)
- we now prefer the last focused window in the current tabgroup to
the actual last focused window on the whole screen.
fluxbox.hh/cc Screen.hh/cc Window.hh/cc Workspace.hh/cc FbWinFrame.cc
*04/03/19:
* fluxbox-generate_menu: (Han)
removes the reload-menu code which is obsolete

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: FbWinFrame.cc,v 1.76 2004/02/28 16:54:04 fluxgen Exp $
// $Id: FbWinFrame.cc,v 1.77 2004/03/21 09:00:24 rathnor Exp $
#include "FbWinFrame.hh"
@ -301,10 +301,11 @@ void FbWinFrame::removeLabelButton(FbTk::TextButton &btn) {
if (erase_it == m_labelbuttons.end())
return;
if (&btn == m_current_label)
m_current_label = 0;
m_labelbuttons.erase(erase_it);
if (*erase_it == m_current_label)
m_current_label = 0;
}

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.cc,v 1.269 2004/03/18 14:45:56 fluxgen Exp $
// $Id: Screen.cc,v 1.270 2004/03/21 09:00:24 rathnor Exp $
#include "Screen.hh"
@ -937,7 +937,7 @@ void BScreen::removeWindow(FluxboxWindow *win) {
if (win->isIconic())
removeIcon(win);
else
getWorkspace(win->workspaceNumber())->removeWindow(win);
getWorkspace(win->workspaceNumber())->removeWindow(win, false);
}
@ -951,13 +951,6 @@ void BScreen::removeClient(WinClient &client) {
focused_list.remove(&client);
if (cyc == &client) {
cycling_window = focused_list.end();
} else if (focused == &client) {
// if we are focused, then give our focus to our transient parent
// or revert normally
if (client.transientFor() && client.transientFor()->fbwindow())
client.transientFor()->fbwindow()->setInputFocus();
else
Fluxbox::instance()->revertFocus(focused->screen());
}
if (cycling_last == &client)
@ -1471,7 +1464,7 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
// gets updated
m_clientlist_sig.notify();
} else if (ignore_sticky || ! w->isStuck()) {
getWorkspace(w->workspaceNumber())->removeWindow(w);
getWorkspace(w->workspaceNumber())->removeWindow(w, true);
getWorkspace(wkspc_id)->addWindow(*w);
// see comment above
m_clientlist_sig.notify();
@ -2544,8 +2537,25 @@ WinClient *BScreen::getLastFocusedWindow(int workspace) {
return 0;
}
/**
* Used to find out which window was last active in the given group
* If ignore_client is given, it excludes that client.
* Stuck, iconic etc don't matter within a group
*/
WinClient *BScreen::getLastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client) {
if (focused_list.empty()) return 0;
FocusedWindows::iterator it = focused_list.begin();
FocusedWindows::iterator it_end = focused_list.end();
for (; it != it_end; ++it) {
if (((*it)->fbwindow() == &group) &&
(*it) != ignore_client)
return *it;
}
return 0;
}
void BScreen::updateSize() {
cerr<<"update Size"<<endl;
// force update geometry
rootWindow().updateGeometry();

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.hh,v 1.134 2004/01/19 18:28:58 fluxgen Exp $
// $Id: Screen.hh,v 1.135 2004/03/21 09:00:25 rathnor Exp $
#ifndef SCREEN_HH
#define SCREEN_HH
@ -147,6 +147,7 @@ public:
inline const FocusedWindows &getFocusedList() const { return focused_list; }
inline FocusedWindows &getFocusedList() { return focused_list; }
WinClient *getLastFocusedWindow(int workspace = -1);
WinClient *getLastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0);
const Workspaces &getWorkspacesList() const { return m_workspaces_list; }
Workspaces &getWorkspacesList() { return m_workspaces_list; }
const WorkspaceNames &getWorkspaceNames() const { return m_workspace_names; }

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Window.cc,v 1.270 2004/03/08 12:20:31 rathnor Exp $
// $Id: Window.cc,v 1.271 2004/03/21 09:00:25 rathnor Exp $
#include "Window.hh"
@ -784,15 +784,11 @@ bool FluxboxWindow::removeClient(WinClient &client) {
// if it is our active client, deal with it...
if (m_client == &client) {
// set next client to be focused
// if the client we're about to remove is the last client then set prev client
if (&client == m_clientlist.back())
prevClient();
else
nextClient();
WinClient *next_client = screen().getLastFocusedWindow(*this, m_client);
if (next_client != 0)
setCurrentClient(*next_client, false);
}
client.m_win = 0;
m_clientlist.remove(&client);
if (m_client == &client) {
@ -815,12 +811,12 @@ bool FluxboxWindow::removeClient(WinClient &client) {
}
m_labelbuttons.erase(&client);
frame().reconfigure();
updateClientLeftWindow();
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"] numClients = "<<numClients()<<endl;
#endif // DEBUG
#endif // DEBUG
return true;
}
@ -905,6 +901,9 @@ void FluxboxWindow::moveClientRight() {
/// Update LEFT window atom on all clients.
void FluxboxWindow::updateClientLeftWindow() {
if (clientList().empty())
return;
// It should just update the affected clients but that
// would require more complex code and we're assuming
// the user dont have alot of windows grouped so this
@ -929,8 +928,11 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
m_client = &client;
m_client->raise();
// frame focused doesn't necessarily mean input focused
frame().setLabelButtonFocus(*m_labelbuttons[m_client]);
if (setinput && setInputFocus()) {
frame().setLabelButtonFocus(*m_labelbuttons[m_client]);
return true;
}
@ -1242,7 +1244,6 @@ bool FluxboxWindow::setInputFocus() {
} else {
ret = m_client->sendFocus();
}
return ret;
}
@ -1296,10 +1297,7 @@ void FluxboxWindow::iconify() {
}
}
WinClient *focused_client = Fluxbox::instance()->getFocusedWindow();
if (focused_client && focused_client->fbwindow() == this)
Fluxbox::instance()->revertFocus(screen());
// focus revert is done elsewhere (based on signal)
}
void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Window.hh,v 1.109 2004/02/20 09:07:27 fluxgen Exp $
// $Id: Window.hh,v 1.110 2004/03/21 09:00:25 rathnor Exp $
#ifndef WINDOW_HH
#define WINDOW_HH
@ -281,6 +281,7 @@ public:
inline bool isResizing() const { return resizing; }
bool isGroupable() const;
inline int numClients() const { return m_clientlist.size(); }
inline bool empty() const { return m_clientlist.empty(); }
inline ClientList &clientList() { return m_clientlist; }
inline const ClientList &clientList() const { return m_clientlist; }
inline WinClient &winClient() { return *m_client; }
@ -370,6 +371,7 @@ public:
};
bool oplock; ///< Used to help stop transient loops occurring by locking a window during certain operations
private:
static const int PropBlackboxAttributesElements = 8;

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Workspace.cc,v 1.94 2004/03/15 23:36:13 rathnor Exp $
// $Id: Workspace.cc,v 1.95 2004/03/21 09:00:25 rathnor Exp $
#include "Workspace.hh"
@ -167,8 +167,11 @@ void Workspace::addWindow(FluxboxWindow &w, bool place) {
}
int Workspace::removeWindow(FluxboxWindow *w) {
// still_alive is true if the window will continue to exist after
// this event. Particularly, this isn't the removeWindow for
// the destruction of the window. Because if so, the focus revert
// is done in another place
int Workspace::removeWindow(FluxboxWindow *w, bool still_alive) {
if (w == 0)
return -1;
@ -180,27 +183,8 @@ int Workspace::removeWindow(FluxboxWindow *w) {
m_lastfocus = 0;
}
if (w->isFocused()) {
if (screen().isSloppyFocus()) {
Fluxbox::instance()->revertFocus(screen());
} else {
// go up the transient tree looking for a focusable window
WinClient *client = 0;
if (w->numClients() > 0) {
client = w->winClient().transientFor();
while (client) {
if (client->fbwindow() &&
client->fbwindow() != w && // can't be this window
client->fbwindow()->isVisible() &&
client->fbwindow()->setCurrentClient(*client, true))
break;
client = client->transientFor();
}
}
if (client == 0) // we were unsuccessful
Fluxbox::instance()->revertFocus(screen());
}
}
if (w->isFocused() && still_alive)
Fluxbox::instance()->unfocusWindow(w->winClient(), true, true);
// we don't remove it from the layermanager, as it may be being moved
Windows::iterator erase_it = remove(m_windowlist.begin(),

View file

@ -62,7 +62,7 @@ public:
void reconfigure();
void shutdown();
void addWindow(FluxboxWindow &win, bool place = false);
int removeWindow(FluxboxWindow *win);
int removeWindow(FluxboxWindow *win, bool still_alive);
void updateClientmenu();
BScreen &screen() { return m_screen; }

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: fluxbox.cc,v 1.234 2004/03/03 12:53:06 rathnor Exp $
// $Id: fluxbox.cc,v 1.235 2004/03/21 09:00:25 rathnor Exp $
#include "fluxbox.hh"
@ -1321,7 +1321,7 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
if (win.isIconic()) {
Workspace *space = win.screen().getWorkspace(win.workspaceNumber());
if (space != 0)
space->removeWindow(&win);
space->removeWindow(&win, true);
win.screen().addIcon(&win);
}
@ -1409,8 +1409,14 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
// finaly send notify signal
screen.updateNetizenWindowDel(client.window());
if (m_focused_window == &client)
revertFocus(screen);
// At this point, we trust that this client is no longer in the
// client list of its frame (but it still has reference to the frame)
// We also assume that any remaining active one is the last focused one
// This is where we revert focus on window close
// NOWHERE ELSE!!!
if (m_focused_window == &client)
unfocusWindow(client);
// failed to revert focus?
if (m_focused_window == &client)
@ -1992,6 +1998,54 @@ void Fluxbox::revertFocus(BScreen &screen) {
}
}
/*
* Like revertFocus, but specifically related to this window (transients etc)
* if full_revert, we fallback to a full revertFocus if we can't find anything
* local to the client.
* If unfocus_frame is true, we won't focus anything in the same frame
* as the client.
*
* So, we first prefer to choose a transient parent, then the last
* client in this window, and if no luck (or unfocus_frame), then
* we just use the normal revertFocus on the screen.
*
* assumption: client has focus
*/
void Fluxbox::unfocusWindow(WinClient &client, bool full_revert, bool unfocus_frame) {
// go up the transient tree looking for a focusable window
FluxboxWindow *fbwin = client.fbwindow();
if (fbwin == 0)
unfocus_frame = false;
WinClient *trans_parent = client.transientFor();
while (trans_parent) {
if (trans_parent->fbwindow() && // can't focus if no fbwin
(!unfocus_frame || trans_parent->fbwindow() != fbwin) && // can't be this window
trans_parent->fbwindow()->isVisible() &&
trans_parent->fbwindow()->setCurrentClient(*trans_parent, m_focused_window == &client)) {
return;
}
trans_parent = trans_parent->transientFor();
}
if (fbwin == 0)
return; // nothing more we can do
BScreen &screen = fbwin->screen();
if (!unfocus_frame) {
WinClient *last_focus = screen.getLastFocusedWindow(*fbwin, &client);
if (last_focus != 0 &&
fbwin->setCurrentClient(*last_focus, m_focused_window == &client)) {
return;
}
}
if (full_revert && m_focused_window == &client)
revertFocus(screen);
}
void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: fluxbox.hh,v 1.83 2004/02/10 18:45:57 fluxgen Exp $
// $Id: fluxbox.hh,v 1.84 2004/03/21 09:00:25 rathnor Exp $
#ifndef FLUXBOX_HH
#define FLUXBOX_HH
@ -157,6 +157,8 @@ public:
void setFocusedWindow(WinClient *w);
void revertFocus(BScreen &screen);
// like revertFocus, but specifically related to this window (transients etc)
void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false);
void shutdown();
void load_rc(BScreen &scr);
void loadRootCommand(BScreen &scr);