various refactoring and minor changes
This commit is contained in:
parent
2c4e1f9a02
commit
97f7c3e1b5
9 changed files with 182 additions and 243 deletions
126
src/Ewmh.cc
126
src/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,95 +238,59 @@ void Ewmh::setupFrame(FluxboxWindow &win) {
|
|||
*
|
||||
*/
|
||||
|
||||
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,
|
||||
(unsigned char **) &data) && data) {
|
||||
|
@ -929,11 +883,7 @@ bool Ewmh::propertyNotify(WinClient &winclient, Atom the_property) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,32 +167,17 @@ void FocusControl::cycleFocus(const Focusables &window_list,
|
|||
|
||||
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 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) {
|
|||
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)
|
||||
|
|
|
@ -46,6 +46,17 @@ public:
|
|||
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
|
||||
|
@ -87,6 +98,9 @@ public:
|
|||
/// @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; }
|
||||
|
||||
|
|
|
@ -390,6 +390,11 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key,
|
|||
// 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;
|
||||
|
|
100
src/WinClient.cc
100
src/WinClient.cc
|
@ -79,13 +79,13 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):
|
|||
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 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):
|
|||
updateWMNormalHints();
|
||||
updateWMClassHint();
|
||||
updateTitle();
|
||||
updateIconTitle();
|
||||
Fluxbox::instance()->saveWindowSearch(win, this);
|
||||
if (window_group != None)
|
||||
Fluxbox::instance()->saveGroupSearch(window_group, this);
|
||||
|
@ -167,11 +166,17 @@ WinClient::~WinClient() {
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -236,12 +241,6 @@ string WinClient::getWMRole() const {
|
|||
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() {
|
||||
XClassHint ch;
|
||||
if (XGetClassHint(display(), window(), &ch) == 0) {
|
||||
|
@ -369,48 +368,6 @@ void WinClient::setTitle(FbTk::FbString &title) {
|
|||
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::updateMWMHints() {
|
|||
|
||||
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 @@ void WinClient::updateWMHints() {
|
|||
* 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);
|
||||
|
|
|
@ -64,9 +64,7 @@ public:
|
|||
|
||||
// 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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
// 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 @@ public:
|
|||
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,17 +163,15 @@ private:
|
|||
// 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
|
||||
// (used if transient_for FbWindow was created after transient)
|
||||
|
|
116
src/Window.cc
116
src/Window.cc
|
@ -453,6 +453,8 @@ void FluxboxWindow::init() {
|
|||
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 @@ void FluxboxWindow::associateClientWindow(bool use_attrs,
|
|||
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 @@ bool FluxboxWindow::focus() {
|
|||
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 @@ void FluxboxWindow::restoreAttributes() {
|
|||
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 @@ void FluxboxWindow::propertyNotifyEvent(WinClient &client, Atom atom) {
|
|||
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 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
|
|||
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 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) {
|
|||
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 @@ void FluxboxWindow::startMoving(int x, int y) {
|
|||
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 @@ void FluxboxWindow::placeWindow(int head) {
|
|||
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
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -459,6 +459,8 @@ public:
|
|||
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(); }
|
||||
|
|
|
@ -301,9 +301,12 @@ void ShowDesktopCmd::execute() {
|
|||
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() {
|
||||
|
|
Loading…
Reference in a new issue