add most recently used window cycling (Simon)
It is now the default cycling action
This commit is contained in:
parent
1aa5ede1b7
commit
58e19dc91e
9 changed files with 289 additions and 80 deletions
|
@ -1,5 +1,8 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 0.9.1:
|
||||
*03/04/15:
|
||||
* Add most recently used/stacked window cycling, set as default (Simon)
|
||||
Window.cc Screen.hh/cc fluxbox.hh/cc Keys.hh/cc
|
||||
*03/04/14:
|
||||
* Don't create menuconfig during install and style cleanups (Han)
|
||||
fluxbox_generate_menu
|
||||
|
|
2
RoadMap
2
RoadMap
|
@ -82,7 +82,7 @@ Major Features:
|
|||
* Toolbar modes (Simon)
|
||||
= Tabs embedded in titlebar (Henrik)
|
||||
= Tabgroup rewrite (Henrik)
|
||||
= Most recently used window cycling (Simon)
|
||||
* Most recently used window cycling (Simon)
|
||||
Minor Features:
|
||||
- per workspace backgrounds (Simon)
|
||||
- more keybinding actions (Both)
|
||||
|
|
48
src/Keys.cc
48
src/Keys.cc
|
@ -19,7 +19,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//$Id: Keys.cc,v 1.24 2003/04/14 12:10:16 fluxgen Exp $
|
||||
//$Id: Keys.cc,v 1.25 2003/04/15 00:50:24 rathnor Exp $
|
||||
|
||||
|
||||
#include "Keys.hh"
|
||||
|
@ -140,14 +140,18 @@ Keys::Keys(const char *filename):
|
|||
m_numlock_mod(0),
|
||||
m_scrolllock_mod(0),
|
||||
m_abortkey(0),
|
||||
m_display(FbTk::App::instance()->display())
|
||||
m_display(FbTk::App::instance()->display()),
|
||||
m_modmap(0)
|
||||
{
|
||||
determineModmap();
|
||||
loadModmap();
|
||||
if (filename != 0)
|
||||
load(filename);
|
||||
}
|
||||
|
||||
Keys::~Keys() {
|
||||
if (m_modmap) {
|
||||
XFreeModifiermap(m_modmap);
|
||||
}
|
||||
ungrabKeys();
|
||||
deleteTree();
|
||||
}
|
||||
|
@ -458,7 +462,7 @@ unsigned int Keys::getKey(const char *keystr) {
|
|||
Keys::KeyAction Keys::getAction(XKeyEvent *ke) {
|
||||
static t_key *next_key = 0;
|
||||
//remove numlock, capslock and scrolllock
|
||||
ke->state &= ~Mod2Mask & ~Mod5Mask & ~LockMask;
|
||||
ke->state = cleanMods(ke->state);
|
||||
|
||||
if (m_abortkey && *m_abortkey==ke) { //abort current keychain
|
||||
next_key = 0;
|
||||
|
@ -636,9 +640,14 @@ Keys::t_key::~t_key() {
|
|||
}
|
||||
|
||||
/**
|
||||
determines modifier mapping for caps, num and scroll lock
|
||||
*/
|
||||
void Keys::determineModmap() {
|
||||
* load state relating to the modifier map
|
||||
*/
|
||||
void Keys::loadModmap() {
|
||||
if (m_modmap) {
|
||||
XFreeModifiermap(m_modmap);
|
||||
}
|
||||
m_modmap = XGetModifierMapping(m_display);
|
||||
|
||||
// mask to use for modifier
|
||||
int mods[] = {
|
||||
ShiftMask,
|
||||
|
@ -652,15 +661,14 @@ void Keys::determineModmap() {
|
|||
0
|
||||
};
|
||||
|
||||
XModifierKeymap *map = XGetModifierMapping(m_display);
|
||||
// find modifiers and set them
|
||||
for (int i=0, realkey=0; i<8; ++i) {
|
||||
for (int key=0; key<map->max_keypermod; ++key, ++realkey) {
|
||||
for (int key=0; key<m_modmap->max_keypermod; ++key, ++realkey) {
|
||||
|
||||
if (map->modifiermap[realkey] == 0)
|
||||
if (m_modmap->modifiermap[realkey] == 0)
|
||||
continue;
|
||||
|
||||
KeySym ks = XKeycodeToKeysym(m_display, map->modifiermap[realkey], 0);
|
||||
KeySym ks = XKeycodeToKeysym(m_display, m_modmap->modifiermap[realkey], 0);
|
||||
|
||||
switch (ks) {
|
||||
case XK_Caps_Lock:
|
||||
|
@ -675,5 +683,21 @@ void Keys::determineModmap() {
|
|||
}
|
||||
}
|
||||
}
|
||||
XFreeModifiermap(map);
|
||||
}
|
||||
|
||||
unsigned int Keys::keycodeToModmask(unsigned int keycode) {
|
||||
if (!m_modmap) return 0;
|
||||
|
||||
// search through modmap for this keycode
|
||||
for (int mod=0; mod < 8; mod++) {
|
||||
for (int key=0; key < m_modmap->max_keypermod; ++key) {
|
||||
// modifiermap is an array with 8 sets of keycodes
|
||||
// each max_keypermod long, but in a linear array.
|
||||
if (m_modmap->modifiermap[m_modmap->max_keypermod*mod + key] == keycode) {
|
||||
return (1<<mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
// no luck
|
||||
return 0;
|
||||
}
|
||||
|
|
17
src/Keys.hh
17
src/Keys.hh
|
@ -19,7 +19,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Keys.hh,v 1.21 2003/04/14 12:10:14 fluxgen Exp $
|
||||
// $Id: Keys.hh,v 1.22 2003/04/15 00:50:24 rathnor Exp $
|
||||
|
||||
#ifndef KEYS_HH
|
||||
#define KEYS_HH
|
||||
|
@ -74,6 +74,18 @@ public:
|
|||
explicit Keys(const char *filename=0);
|
||||
/// destructor
|
||||
~Keys();
|
||||
|
||||
/**
|
||||
Strip out modifiers we want to ignore
|
||||
@return the cleaned state number
|
||||
*/
|
||||
static unsigned int cleanMods(unsigned int mods)
|
||||
//remove numlock, capslock and scrolllock
|
||||
{ return mods & (~Mod2Mask & ~Mod5Mask & ~LockMask);}
|
||||
|
||||
unsigned int keycodeToModmask(unsigned int keycode);
|
||||
void loadModmap();
|
||||
|
||||
/**
|
||||
Load configuration from file
|
||||
@return true on success, else false
|
||||
|
@ -170,8 +182,6 @@ private:
|
|||
/// debug function
|
||||
void showKeyTree(t_key *key, unsigned int w=0);
|
||||
#endif //DEBUG
|
||||
/// determine key modifier maps for caps-, num- and scrolllock
|
||||
void determineModmap();
|
||||
|
||||
struct t_actionstr{
|
||||
const char *string;
|
||||
|
@ -187,6 +197,7 @@ private:
|
|||
std::string m_execcmdstring; ///< copy of the execcommandstring
|
||||
int m_param; ///< copy of the param argument
|
||||
Display *m_display; ///< display connection
|
||||
XModifierKeymap *m_modmap; // Modifier->keycode mapping
|
||||
};
|
||||
|
||||
#endif // _KEYS_HH_
|
||||
|
|
189
src/Screen.cc
189
src/Screen.cc
|
@ -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.119 2003/04/14 14:49:47 fluxgen Exp $
|
||||
// $Id: Screen.cc,v 1.120 2003/04/15 00:50:24 rathnor Exp $
|
||||
|
||||
|
||||
#include "Screen.hh"
|
||||
|
@ -407,6 +407,7 @@ BScreen::BScreen(ResourceManager &rm,
|
|||
m_workspacenames_sig(*this), // workspace names signal
|
||||
m_currentworkspace_sig(*this), // current workspace signal
|
||||
m_layermanager(num_layers),
|
||||
cycling_focus(false),
|
||||
theme(0), m_windowtheme(scrn),
|
||||
m_menutheme(new FbTk::MenuTheme(scrn)),
|
||||
resource(rm, screenname, altscreenname),
|
||||
|
@ -449,6 +450,7 @@ BScreen::BScreen(ResourceManager &rm,
|
|||
(unsigned char *) &bpid, 1);
|
||||
#endif // HAVE_GETPID
|
||||
|
||||
cycling_window = focused_list.end();
|
||||
|
||||
XDefineCursor(disp, getRootWindow(), fluxbox->getSessionCursor());
|
||||
|
||||
|
@ -841,6 +843,15 @@ void BScreen::removeWindow(FluxboxWindow *win) {
|
|||
(*it)->removeWindow(win);
|
||||
}
|
||||
|
||||
|
||||
void BScreen::removeClient(WinClient &client) {
|
||||
WinClient *cyc = *cycling_window;
|
||||
focused_list.remove(&client);
|
||||
if (cyc == &client) {
|
||||
cycling_window = focused_list.end();
|
||||
}
|
||||
}
|
||||
|
||||
FluxboxWindow *BScreen::getIcon(unsigned int index) {
|
||||
if (index < iconList.size())
|
||||
return iconList[index];
|
||||
|
@ -1130,12 +1141,17 @@ FluxboxWindow *BScreen::createWindow(Window client) {
|
|||
delete win;
|
||||
return 0;
|
||||
} else {
|
||||
// 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
|
||||
focused_list.push_back(&win->winClient());
|
||||
|
||||
//TODO: is next line needed?
|
||||
Fluxbox::instance()->saveWindowSearch(client, win);
|
||||
Fluxbox::instance()->attachSignals(*win);
|
||||
setupWindowActions(*win);
|
||||
}
|
||||
if (win->getWorkspaceNumber() == getCurrentWorkspaceID() || win->isStuck()) {
|
||||
win->show();
|
||||
win->show();
|
||||
}
|
||||
XSync(FbTk::App::instance()->display(), False);
|
||||
return win;
|
||||
|
@ -1153,6 +1169,9 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) {
|
|||
delete win;
|
||||
return 0;
|
||||
}
|
||||
// don't add to focused_list, as it should already be in there (since the
|
||||
// WinClient already exists).
|
||||
|
||||
Fluxbox::instance()->saveWindowSearch(client.window(), win);
|
||||
Fluxbox::instance()->attachSignals(*win);
|
||||
setupWindowActions(*win);
|
||||
|
@ -1343,27 +1362,58 @@ void BScreen::nextFocus(int opts) {
|
|||
}
|
||||
|
||||
if (num_windows >= 1) {
|
||||
Workspace *wksp = getCurrentWorkspace();
|
||||
Workspace::Windows &wins = wksp->getWindowList();
|
||||
Workspace::Windows::iterator it = wins.begin();
|
||||
if (!(opts & CYCLELINEAR)) {
|
||||
if (!cycling_focus) {
|
||||
cycling_focus = True;
|
||||
cycling_window = focused_list.begin();
|
||||
}
|
||||
// if it is stacked, we want the highest window in the focused list
|
||||
// that is on the same workspace
|
||||
FocusedWindows::iterator it = cycling_window;
|
||||
FocusedWindows::iterator it_end = focused_list.end();
|
||||
|
||||
if (!have_focused) {
|
||||
focused = (*it);
|
||||
} else {
|
||||
for (; (*it) != focused; ++it) //get focused window iterator
|
||||
continue;
|
||||
while (true) {
|
||||
++it;
|
||||
if (it == it_end) {
|
||||
it = focused_list.begin();
|
||||
}
|
||||
// give up [do nothing] if we reach the current focused again
|
||||
if ((*it) == (*cycling_window)) {
|
||||
break;
|
||||
}
|
||||
|
||||
FluxboxWindow *fbwin = (*it)->m_win;
|
||||
if (fbwin && !fbwin->isIconic() &&
|
||||
(fbwin->isStuck()
|
||||
|| fbwin->getWorkspaceNumber() == getCurrentWorkspaceID())) {
|
||||
// either on this workspace, or stuck
|
||||
if (! (doSkipWindow(fbwin, opts) || !fbwin->setInputFocus()) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
cycling_window = it;
|
||||
} else { // not stacked cycling
|
||||
Workspace *wksp = getCurrentWorkspace();
|
||||
Workspace::Windows &wins = wksp->getWindowList();
|
||||
Workspace::Windows::iterator it = wins.begin();
|
||||
|
||||
if (!have_focused) {
|
||||
focused = (*it);
|
||||
} else {
|
||||
for (; (*it) != focused; ++it) //get focused window iterator
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
++it;
|
||||
if (it == wins.end())
|
||||
it = wins.begin();
|
||||
// see if the window should be skipped
|
||||
if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
|
||||
break;
|
||||
} while ((*it) != focused);
|
||||
if ((*it) != focused && it != wins.end())
|
||||
(*it)->raise();
|
||||
}
|
||||
do {
|
||||
++it;
|
||||
if (it == wins.end())
|
||||
it = wins.begin();
|
||||
// see if the window should be skipped
|
||||
if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
|
||||
break;
|
||||
} while ((*it) != focused);
|
||||
|
||||
if ((*it) != focused && it != wins.end())
|
||||
(*it)->raise();
|
||||
|
||||
}
|
||||
|
||||
|
@ -1385,29 +1435,62 @@ void BScreen::prevFocus(int opts) {
|
|||
}
|
||||
|
||||
if (num_windows >= 1) {
|
||||
Workspace *wksp = getCurrentWorkspace();
|
||||
Workspace::Windows &wins = wksp->getWindowList();
|
||||
Workspace::Windows::iterator it = wins.begin();
|
||||
if (!(opts & CYCLELINEAR)) {
|
||||
if (!cycling_focus) {
|
||||
cycling_focus = True;
|
||||
cycling_window = focused_list.end();
|
||||
}
|
||||
// if it is stacked, we want the highest window in the focused list
|
||||
// that is on the same workspace
|
||||
FocusedWindows::iterator it = cycling_window;
|
||||
FocusedWindows::iterator it_end = focused_list.end();
|
||||
|
||||
if (!have_focused) {
|
||||
focused = (*it);
|
||||
} else {
|
||||
for (; (*it) != focused; ++it) //get focused window iterator
|
||||
continue;
|
||||
while (true) {
|
||||
--it;
|
||||
if (it == it_end) {
|
||||
it = focused_list.end();
|
||||
--it;
|
||||
}
|
||||
// give up [do nothing] if we reach the current focused again
|
||||
if ((*it) == (*cycling_window)) {
|
||||
break;
|
||||
}
|
||||
|
||||
FluxboxWindow *fbwin = (*it)->m_win;
|
||||
if (fbwin && !fbwin->isIconic() &&
|
||||
(fbwin->isStuck()
|
||||
|| fbwin->getWorkspaceNumber() == getCurrentWorkspaceID())) {
|
||||
// either on this workspace, or stuck
|
||||
if (! (doSkipWindow(fbwin, opts) || !fbwin->setInputFocus()) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
cycling_window = it;
|
||||
} else { // not stacked cycling
|
||||
|
||||
Workspace *wksp = getCurrentWorkspace();
|
||||
Workspace::Windows &wins = wksp->getWindowList();
|
||||
Workspace::Windows::iterator it = wins.begin();
|
||||
|
||||
if (!have_focused) {
|
||||
focused = (*it);
|
||||
} else {
|
||||
for (; (*it) != focused; ++it) //get focused window iterator
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
if (it == wins.begin())
|
||||
it = wins.end();
|
||||
--it;
|
||||
// see if the window should be skipped
|
||||
if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
|
||||
break;
|
||||
} while ((*it) != focused);
|
||||
|
||||
if ((*it) != focused && it != wins.end())
|
||||
(*it)->raise();
|
||||
}
|
||||
|
||||
do {
|
||||
if (it == wins.begin())
|
||||
it = wins.end();
|
||||
--it;
|
||||
// see if the window should be skipped
|
||||
if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) )
|
||||
break;
|
||||
} while ((*it) != focused);
|
||||
|
||||
if ((*it) != focused && it != wins.end())
|
||||
(*it)->raise();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1428,6 +1511,15 @@ void BScreen::raiseFocus() {
|
|||
fb->getFocusedWindow()->raise();
|
||||
}
|
||||
|
||||
void BScreen::setFocusedWindow(WinClient &winclient) {
|
||||
// raise newly focused window to the top of the focused list
|
||||
if (!cycling_focus) { // don't change the order if we're cycling
|
||||
focused_list.remove(&winclient);
|
||||
focused_list.push_front(&winclient);
|
||||
cycling_window = focused_list.begin();
|
||||
}
|
||||
}
|
||||
|
||||
void BScreen::initMenu() {
|
||||
I18n *i18n = I18n::instance();
|
||||
|
||||
|
@ -2059,6 +2151,19 @@ bool BScreen::doSkipWindow(const FluxboxWindow *w, int opts) {
|
|||
(opts & CYCLESKIPSHADED) != 0 && w->isShaded()); // skip if shaded
|
||||
}
|
||||
|
||||
/**
|
||||
Called when a set of watched modifiers has been released
|
||||
*/
|
||||
void BScreen::notifyReleasedKeys(XKeyEvent &ke) {
|
||||
if (cycling_focus) {
|
||||
cycling_focus = false;
|
||||
// put currently focused window to top
|
||||
WinClient *client = *cycling_window;
|
||||
focused_list.erase(cycling_window);
|
||||
focused_list.push_front(client);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Access and clear the auto-group window
|
||||
*/
|
||||
|
|
|
@ -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.74 2003/04/14 12:13:36 fluxgen Exp $
|
||||
// $Id: Screen.hh,v 1.75 2003/04/15 00:50:24 rathnor Exp $
|
||||
|
||||
#ifndef SCREEN_HH
|
||||
#define SCREEN_HH
|
||||
|
@ -151,6 +151,7 @@ public:
|
|||
unsigned int getMaxBottom() const;
|
||||
|
||||
typedef std::vector<FluxboxWindow *> Icons;
|
||||
typedef std::list<WinClient *> FocusedWindows;
|
||||
|
||||
/// @return number of workspaces
|
||||
inline unsigned int getCount() const { return workspacesList.size(); }
|
||||
|
@ -158,6 +159,8 @@ public:
|
|||
inline unsigned int getIconCount() const { return iconList.size(); }
|
||||
inline const Icons &getIconList() const { return iconList; }
|
||||
inline Icons &getIconList() { return iconList; }
|
||||
inline const FocusedWindows &getFocusedList() const { return focused_list; }
|
||||
inline FocusedWindows &getFocusedList() { return focused_list; }
|
||||
const Workspaces &getWorkspacesList() const { return workspacesList; }
|
||||
const WorkspaceNames &getWorkspaceNames() const { return workspaceNames; }
|
||||
/**
|
||||
|
@ -258,6 +261,7 @@ public:
|
|||
void removeIcon(FluxboxWindow *win);
|
||||
// remove window
|
||||
void removeWindow(FluxboxWindow *win);
|
||||
void removeClient(WinClient &client);
|
||||
|
||||
std::string getNameOfWorkspace(unsigned int workspace) const;
|
||||
void changeWorkspaceID(unsigned int);
|
||||
|
@ -269,6 +273,8 @@ public:
|
|||
void prevFocus(int options);
|
||||
void nextFocus(int options);
|
||||
void raiseFocus();
|
||||
void setFocusedWindow(WinClient &winclient);
|
||||
|
||||
void reconfigure();
|
||||
void rereadMenu();
|
||||
void shutdown();
|
||||
|
@ -276,6 +282,8 @@ public:
|
|||
void showGeometry(unsigned int, unsigned int);
|
||||
void hideGeometry();
|
||||
|
||||
void notifyReleasedKeys(XKeyEvent &ke);
|
||||
|
||||
void setLayer(FbTk::XLayerItem &item, int layernum);
|
||||
// remove? no, items are never removed from their layer until they die
|
||||
|
||||
|
@ -306,7 +314,7 @@ public:
|
|||
WINDOWLOWER, WINDOWSTICK, WINDOWKILL, SETSTYLE, WINDOWTAB};
|
||||
// prevFocus/nextFocus option bits
|
||||
enum { CYCLESKIPLOWERTABS = 0x01, CYCLESKIPSTUCK = 0x02, CYCLESKIPSHADED = 0x04,
|
||||
CYCLEDEFAULT = 0x00 };
|
||||
CYCLELINEAR = 0x08, CYCLEDEFAULT = 0x00 };
|
||||
|
||||
class ScreenSubject:public FbTk::Subject {
|
||||
public:
|
||||
|
@ -334,10 +342,8 @@ private:
|
|||
m_currentworkspace_sig; ///< current workspace signal
|
||||
|
||||
FbTk::MultLayers m_layermanager;
|
||||
//!!
|
||||
Theme *theme; ///< obsolete
|
||||
|
||||
Bool root_colormap_installed, managed, geom_visible;
|
||||
Bool root_colormap_installed, managed, geom_visible, cycling_focus;
|
||||
GC opGC;
|
||||
Pixmap geom_pixmap;
|
||||
FbTk::FbWindow geom_window;
|
||||
|
@ -353,6 +359,12 @@ private:
|
|||
Rootmenus rootmenuList;
|
||||
Netizens netizenList;
|
||||
Icons iconList;
|
||||
|
||||
// This list keeps the order of window focusing for this screen
|
||||
// Screen global so it works for sticky windows too.
|
||||
FocusedWindows focused_list;
|
||||
FocusedWindows::iterator cycling_window;
|
||||
|
||||
#ifdef SLIT
|
||||
std::auto_ptr<Slit> m_slit;
|
||||
#endif // SLIT
|
||||
|
@ -368,6 +380,9 @@ private:
|
|||
|
||||
Window auto_group_window;
|
||||
|
||||
//!!
|
||||
Theme *theme; ///< obsolete
|
||||
|
||||
FbWinFrameTheme m_windowtheme;
|
||||
std::auto_ptr<FbTk::MenuTheme> m_menutheme;
|
||||
|
||||
|
|
|
@ -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.131 2003/04/14 14:58:12 fluxgen Exp $
|
||||
// $Id: Window.cc,v 1.132 2003/04/15 00:50:25 rathnor Exp $
|
||||
|
||||
#include "Window.hh"
|
||||
|
||||
|
@ -1143,7 +1143,8 @@ bool FluxboxWindow::setInputFocus() {
|
|||
}
|
||||
|
||||
m_frame.setFocus(true);
|
||||
|
||||
screen.setFocusedWindow(*m_client);
|
||||
|
||||
Fluxbox::instance()->setFocusedWindow(this);
|
||||
|
||||
if (send_focus_message)
|
||||
|
|
|
@ -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.106 2003/04/14 15:28:52 fluxgen Exp $
|
||||
// $Id: fluxbox.cc,v 1.107 2003/04/15 00:50:25 rathnor Exp $
|
||||
|
||||
#include "fluxbox.hh"
|
||||
|
||||
|
@ -373,6 +373,7 @@ Fluxbox::Fluxbox(int m_argc, char **m_argv, const char *dpy_name, const char *rc
|
|||
m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"),
|
||||
focused_window(0), masked_window(0),
|
||||
timer(this),
|
||||
watching_screen(0), watch_keyrelease(0),
|
||||
no_focus(false),
|
||||
rc_file(rc ? rc : ""),
|
||||
argv(m_argv), argc(m_argc),
|
||||
|
@ -699,6 +700,15 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
case UnmapNotify:
|
||||
handleUnmapNotify(e->xunmap);
|
||||
break;
|
||||
case MappingNotify:
|
||||
// Update stored modifier mapping
|
||||
#ifdef DEBUG
|
||||
cerr<<__FILE__<<"("<<__FUNCTION__<<"): MappingNotify"<<endl;
|
||||
#endif // DEBUG
|
||||
if (key.get()) {
|
||||
key->loadModmap();
|
||||
}
|
||||
break;
|
||||
case CreateNotify:
|
||||
break;
|
||||
case DestroyNotify: {
|
||||
|
@ -767,6 +777,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
|
||||
}
|
||||
break;
|
||||
case KeyRelease:
|
||||
case KeyPress:
|
||||
handleKeyEvent(e->xkey);
|
||||
break;
|
||||
|
@ -1136,9 +1147,19 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) {
|
|||
}
|
||||
break;
|
||||
case Keys::NEXTWINDOW: //activate next window
|
||||
if (!watching_screen && !(key->getParam() & BScreen::CYCLELINEAR)) {
|
||||
// if stacked cycling, then set a watch for
|
||||
// the release of exactly these modifiers
|
||||
watchKeyRelease(screen, Keys::cleanMods(ke.state));
|
||||
}
|
||||
screen->nextFocus(key->getParam());
|
||||
break;
|
||||
case Keys::PREVWINDOW: //activate prev window
|
||||
if (!watching_screen && !(key->getParam() & BScreen::CYCLELINEAR)) {
|
||||
// if stacked cycling, then set a watch for
|
||||
// the release of exactly these modifiers
|
||||
watchKeyRelease(screen, Keys::cleanMods(ke.state));
|
||||
}
|
||||
screen->prevFocus(key->getParam());
|
||||
break;
|
||||
case Keys::NEXTTAB:
|
||||
|
@ -1242,7 +1263,30 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) {
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyRelease:
|
||||
{
|
||||
// we ignore most key releases unless we need to use
|
||||
// a release to stop something (e.g. window cycling).
|
||||
|
||||
// we notify if _all_ of the watched modifiers are released
|
||||
if (watching_screen && watch_keyrelease) {
|
||||
// mask the mod of the released key out
|
||||
// won't mask anything if it isn't a mod
|
||||
ke.state &= ~key->keycodeToModmask(ke.keycode);
|
||||
|
||||
if ((watch_keyrelease & ke.state) == 0) {
|
||||
|
||||
watching_screen->notifyReleasedKeys(ke);
|
||||
XUngrabKeyboard(getXDisplay(), CurrentTime);
|
||||
|
||||
// once they are released, we drop the watch
|
||||
watching_screen = 0;
|
||||
watch_keyrelease = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1470,10 +1514,7 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
|
|||
}
|
||||
// make sure each workspace get this
|
||||
BScreen &scr = win.getScreen();
|
||||
for (int workspace = 0; workspace < scr.getNumberOfWorkspaces();
|
||||
++workspace) {
|
||||
scr.getWorkspace(workspace)->removeWindow(&win);
|
||||
}
|
||||
scr.removeWindow(&win);
|
||||
|
||||
} else if ((&(win.workspaceSig())) == changedsub) { // workspace signal
|
||||
for (size_t i=0; i<m_atomhandler.size(); ++i) {
|
||||
|
@ -1513,13 +1554,12 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
|
|||
} else if (typeid(*changedsub) == typeid(WinClient::WinClientSubj)) {
|
||||
WinClient::WinClientSubj *subj = dynamic_cast<WinClient::WinClientSubj *>(changedsub);
|
||||
WinClient &client = subj->winClient();
|
||||
//!! TODO we shouldn't call update netizen on every screen
|
||||
// just the screen it was located on
|
||||
ScreenList::iterator screen_it = screenList.begin();
|
||||
const ScreenList::iterator screen_it_end = screenList.end();
|
||||
for (; screen_it != screen_it_end; ++screen_it)
|
||||
(*screen_it)->updateNetizenWindowDel(client.window());
|
||||
|
||||
if (client.fbwindow()) {
|
||||
BScreen &screen = client.fbwindow()->getScreen();
|
||||
screen.updateNetizenWindowDel(client.window());
|
||||
screen.removeClient(client);
|
||||
}
|
||||
|
||||
removeWindowSearch(client.window());
|
||||
//!! TODO
|
||||
|
@ -2232,13 +2272,12 @@ void Fluxbox::setFocusedWindow(FluxboxWindow *win) {
|
|||
if (focused_window != 0) {
|
||||
old_win = focused_window;
|
||||
old_screen = &old_win->getScreen();
|
||||
|
||||
|
||||
old_tbar = old_screen->getToolbar();
|
||||
old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber());
|
||||
|
||||
old_win->setFocusFlag(False);
|
||||
old_wkspc->menu().setItemSelected(old_win->getWindowNumber(), false);
|
||||
|
||||
}
|
||||
|
||||
if (win && ! win->isIconic()) {
|
||||
|
@ -2272,3 +2311,10 @@ void Fluxbox::setFocusedWindow(FluxboxWindow *win) {
|
|||
old_screen->updateNetizenWindowFocus();
|
||||
|
||||
}
|
||||
|
||||
void Fluxbox::watchKeyRelease(BScreen *screen, unsigned int mods) {
|
||||
watching_screen = screen;
|
||||
watch_keyrelease = mods;
|
||||
XGrabKeyboard(getXDisplay(),screen->getRootWindow(), True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
}
|
||||
|
|
|
@ -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.47 2003/04/14 15:25:14 fluxgen Exp $
|
||||
// $Id: fluxbox.hh,v 1.48 2003/04/15 00:50:25 rathnor Exp $
|
||||
|
||||
#ifndef FLUXBOX_HH
|
||||
#define FLUXBOX_HH
|
||||
|
@ -141,6 +141,8 @@ public:
|
|||
{ masked = w; masked_window = bw; }
|
||||
inline void setNoFocus(Bool f) { no_focus = f; }
|
||||
|
||||
void watchKeyRelease(BScreen *screen, unsigned int mods);
|
||||
|
||||
void setFocusedWindow(FluxboxWindow *w);
|
||||
void shutdown();
|
||||
void load_rc(BScreen *);
|
||||
|
@ -236,6 +238,8 @@ private:
|
|||
FluxboxWindow *focused_window, *masked_window;
|
||||
FbTk::Timer timer;
|
||||
|
||||
BScreen *watching_screen;
|
||||
unsigned int watch_keyrelease;
|
||||
|
||||
#ifdef HAVE_GETPID
|
||||
Atom fluxbox_pid;
|
||||
|
|
Loading…
Reference in a new issue