-// openbox.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif // HAVE_CONFIG_H
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xresource.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-
-#ifdef SHAPE
-#include <X11/extensions/shape.h>
-#endif // SHAPE
-
-#include "i18n.h"
-#include "openbox.h"
-#include "Basemenu.h"
-#include "Clientmenu.h"
-#include "Rootmenu.h"
-#include "Screen.h"
-
-#ifdef SLIT
-#include "Slit.h"
-#endif // SLIT
-
-#include "Toolbar.h"
-#include "Window.h"
-#include "Workspace.h"
-#include "Workspacemenu.h"
-#include "Util.h"
-
-#include <string>
-#include <algorithm>
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif
+
+#include "openbox.hh"
+#include "client.hh"
+#include "screen.hh"
+#include "actions.hh"
+#include "bindings.hh"
+#include "python.hh"
+#include "otk/property.hh"
+#include "otk/display.hh"
+#include "otk/assassin.hh"
+#include "otk/util.hh" // TEMPORARY
+
+extern "C" {
+#include <X11/cursorfont.h>
#ifdef HAVE_STDIO_H
# include <stdio.h>
# include <stdlib.h>
#endif // HAVE_STDLIB_H
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif // HAVE_STRING_H
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif // HAVE_SIGNAL_H
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif // HAVE_FCNTL_H
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif // HAVE_UNISTD_H
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif // HAVE_SYS_PARAM_H
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 255
-#endif // MAXPATHLEN
-
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif // HAVE_SYS_SELECT_H
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif // HAVE_SIGNAL_H
-
-#ifdef HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif // HAVE_SYS_SIGNAL_H
-
-#ifdef HAVE_SYS_STAT_H
-# include <sys/types.h>
-# include <sys/stat.h>
-#endif // HAVE_SYS_STAT_H
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
-
-#ifdef HAVE_LIBGEN_H
-# include <libgen.h>
-#endif // HAVE_LIBGEN_H
-
-#ifndef HAVE_BASENAME
-static inline char *basename (char *s) {
- char *save = s;
-
- while (*s) if (*s++ == '/') save = s;
-
- return save;
+#include "gettext.h"
+#define _(str) gettext(str)
}
-#endif // HAVE_BASENAME
-
-
-// X event scanner for enter/leave notifies - adapted from twm
-typedef struct scanargs {
- Window w;
- Bool leave, inferior, enter;
-} scanargs;
-
-static Bool queueScanner(Display *, XEvent *e, char *args) {
- if ((e->type == LeaveNotify) &&
- (e->xcrossing.window == ((scanargs *) args)->w) &&
- (e->xcrossing.mode == NotifyNormal)) {
- ((scanargs *) args)->leave = True;
- ((scanargs *) args)->inferior = (e->xcrossing.detail == NotifyInferior);
- } else if ((e->type == EnterNotify) &&
- (e->xcrossing.mode == NotifyUngrab)) {
- ((scanargs *) args)->enter = True;
- }
-
- return False;
-}
-
-Openbox *openbox;
-
-
-Openbox::Openbox(int m_argc, char **m_argv, char *dpy_name, char *rc)
- : BaseDisplay(m_argv[0], dpy_name) {
- grab();
-
- if (! XSupportsLocale())
- fprintf(stderr, "X server does not support locale\n");
-
- if (XSetLocaleModifiers("") == NULL)
- fprintf(stderr, "cannot set locale modifiers\n");
-
- ::openbox = this;
- argc = m_argc;
- argv = m_argv;
- if (rc == NULL) {
- char *homedir = getenv("HOME");
-
- rc_file = new char[strlen(homedir) + strlen("/.openbox/rc") + 1];
- sprintf(rc_file, "%s/.openbox", homedir);
-
- // try to make sure the ~/.openbox directory exists
- mkdir(rc_file, S_IREAD | S_IWRITE | S_IEXEC | S_IRGRP | S_IWGRP | S_IXGRP |
- S_IROTH | S_IWOTH | S_IXOTH);
-
- sprintf(rc_file, "%s/.openbox/rc", homedir);
- } else {
- rc_file = bstrdup(rc);
- }
- config.setFile(rc_file);
-
- no_focus = False;
-
- resource.menu_file = resource.style_file = NULL;
- resource.titlebar_layout = NULL;
- resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0;
-
- focused_window = masked_window = NULL;
- masked = None;
-
- windowSearchList = new LinkedList<WindowSearch>;
- menuSearchList = new LinkedList<MenuSearch>;
-
-#ifdef SLIT
- slitSearchList = new LinkedList<SlitSearch>;
-#endif // SLIT
-
- toolbarSearchList = new LinkedList<ToolbarSearch>;
- groupSearchList = new LinkedList<WindowSearch>;
-
- menuTimestamps = new LinkedList<MenuTimestamp>;
-
- load();
-
-#ifdef HAVE_GETPID
- openbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False);
-#endif // HAVE_GETPID
-
- screenList = new LinkedList<BScreen>;
- for (int i = 0; i < getNumberOfScreens(); i++) {
- BScreen *screen = new BScreen(*this, i, config);
-
- if (! screen->isScreenManaged()) {
- delete screen;
- continue;
- }
-
- screenList->insert(screen);
- }
-
- if (! screenList->count()) {
- fprintf(stderr,
- i18n->getMessage(openboxSet, openboxNoManagableScreens,
- "Openbox::Openbox: no managable screens found, aborting.\n"));
- ::exit(3);
- }
-
- // save current settings and default values
- save();
-
- XSynchronize(getXDisplay(), False);
- XSync(getXDisplay(), False);
-
- reconfigure_wait = reread_menu_wait = False;
-
- timer = new BTimer(*this, *this);
- timer->setTimeout(0);
- timer->fireOnce(True);
-
- ungrab();
-}
-
-
-Openbox::~Openbox() {
- while (screenList->count())
- delete screenList->remove(0);
-
- while (menuTimestamps->count()) {
- MenuTimestamp *ts = menuTimestamps->remove(0);
-
- if (ts->filename)
- delete [] ts->filename;
-
- delete ts;
- }
-
- if (resource.menu_file)
- delete [] resource.menu_file;
-
- if (resource.style_file)
- delete [] resource.style_file;
-
- if (resource.titlebar_layout)
- delete [] resource.titlebar_layout;
-
- delete timer;
-
- delete screenList;
- delete menuTimestamps;
-
- delete windowSearchList;
- delete menuSearchList;
- delete toolbarSearchList;
- delete groupSearchList;
-
- delete [] rc_file;
-
-#ifdef SLIT
- delete slitSearchList;
-#endif // SLIT
-}
-
-
-void Openbox::process_event(XEvent *e) {
- if ((masked == e->xany.window) && masked_window &&
- (e->type == MotionNotify)) {
- last_time = e->xmotion.time;
- masked_window->motionNotifyEvent(&e->xmotion);
-
- return;
- }
-
- switch (e->type) {
- case ButtonPress: {
- // strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
-
- last_time = e->xbutton.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- Toolbar *tbar = (Toolbar *) 0;
-
- if ((win = searchWindow(e->xbutton.window))) {
- win->buttonPressEvent(&e->xbutton);
-
- if (e->xbutton.button == 1)
- win->installColormap(True);
- } else if ((menu = searchMenu(e->xbutton.window))) {
- menu->buttonPressEvent(&e->xbutton);
-
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xbutton.window))) {
- slit->buttonPressEvent(&e->xbutton);
-#endif // SLIT
-
- } else if ((tbar = searchToolbar(e->xbutton.window))) {
- tbar->buttonPressEvent(&e->xbutton);
- } else {
- LinkedListIterator<BScreen> it(screenList);
- BScreen *screen = it.current();
- for (; screen; it++, screen = it.current()) {
- if (e->xbutton.window == screen->getRootWindow()) {
- if (e->xbutton.button == 1) {
- if (! screen->isRootColormapInstalled())
- screen->getImageControl()->installRootColormap();
-
- if (screen->getWorkspacemenu()->isVisible())
- screen->getWorkspacemenu()->hide();
-
- if (screen->getRootmenu()->isVisible())
- screen->getRootmenu()->hide();
- } else if (e->xbutton.button == 2) {
- int mx = e->xbutton.x_root -
- (screen->getWorkspacemenu()->getWidth() / 2);
- int my = e->xbutton.y_root -
- (screen->getWorkspacemenu()->getTitleHeight() / 2);
-
- if (mx < 0) mx = 0;
- if (my < 0) my = 0;
-
- if (mx + screen->getWorkspacemenu()->getWidth() >
- screen->size().w())
- mx = screen->size().w() -
- screen->getWorkspacemenu()->getWidth() -
- screen->getBorderWidth();
-
- if (my + screen->getWorkspacemenu()->getHeight() >
- screen->size().h())
- my = screen->size().h() -
- screen->getWorkspacemenu()->getHeight() -
- screen->getBorderWidth();
-
- screen->getWorkspacemenu()->move(mx, my);
-
- if (! screen->getWorkspacemenu()->isVisible()) {
- screen->getWorkspacemenu()->removeParent();
- screen->getWorkspacemenu()->show();
- }
- } else if (e->xbutton.button == 3) {
- int mx = e->xbutton.x_root -
- (screen->getRootmenu()->getWidth() / 2);
- int my = e->xbutton.y_root -
- (screen->getRootmenu()->getTitleHeight() / 2);
-
- if (mx < 0) mx = 0;
- if (my < 0) my = 0;
-
- if (mx + screen->getRootmenu()->getWidth() > screen->size().w())
- mx = screen->size().w() -
- screen->getRootmenu()->getWidth() -
- screen->getBorderWidth();
-
- if (my + screen->getRootmenu()->getHeight() > screen->size().h())
- my = screen->size().h() -
- screen->getRootmenu()->getHeight() -
- screen->getBorderWidth();
-
- screen->getRootmenu()->move(mx, my);
-
- if (! screen->getRootmenu()->isVisible()) {
- checkMenu();
- screen->getRootmenu()->show();
- }
- } else if (e->xbutton.button == 4) {
- if ((screen->getCurrentWorkspaceID() + 1) >
- screen->getWorkspaceCount() - 1)
- screen->changeWorkspaceID(0);
- else
- screen->changeWorkspaceID(screen->getCurrentWorkspaceID() + 1);
- } else if (e->xbutton.button == 5) {
- if ((screen->getCurrentWorkspaceID() - 1) < 0)
- screen->changeWorkspaceID(screen->getWorkspaceCount() - 1);
- else
- screen->changeWorkspaceID(screen->getCurrentWorkspaceID() - 1);
- }
- }
- }
- }
-
- break;
- }
-
- case ButtonRelease: {
- // strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
-
- last_time = e->xbutton.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
- if ((win = searchWindow(e->xbutton.window)))
- win->buttonReleaseEvent(&e->xbutton);
- else if ((menu = searchMenu(e->xbutton.window)))
- menu->buttonReleaseEvent(&e->xbutton);
- else if ((tbar = searchToolbar(e->xbutton.window)))
- tbar->buttonReleaseEvent(&e->xbutton);
-
- break;
- }
-
- case ConfigureRequest: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((win = searchWindow(e->xconfigurerequest.window))) {
- win->configureRequestEvent(&e->xconfigurerequest);
-
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xconfigurerequest.window))) {
- slit->configureRequestEvent(&e->xconfigurerequest);
-#endif // SLIT
-
- } else {
- grab();
-
- if (validateWindow(e->xconfigurerequest.window)) {
- XWindowChanges xwc;
-
- xwc.x = e->xconfigurerequest.x;
- xwc.y = e->xconfigurerequest.y;
- xwc.width = e->xconfigurerequest.width;
- xwc.height = e->xconfigurerequest.height;
- xwc.border_width = e->xconfigurerequest.border_width;
- xwc.sibling = e->xconfigurerequest.above;
- xwc.stack_mode = e->xconfigurerequest.detail;
-
- XConfigureWindow(getXDisplay(), e->xconfigurerequest.window,
- e->xconfigurerequest.value_mask, &xwc);
- }
-
- ungrab();
- }
-
- break;
- }
-
- case MapRequest: {
-#ifdef DEBUG
- fprintf(stderr,
- i18n->getMessage(openboxSet, openboxMapRequest,
- "Openbox::process_event(): MapRequest for 0x%lx\n"),
- e->xmaprequest.window);
-#endif // DEBUG
-
- OpenboxWindow *win = searchWindow(e->xmaprequest.window);
-
- if (! win)
- win = new OpenboxWindow(*this, e->xmaprequest.window);
-
- if ((win = searchWindow(e->xmaprequest.window))) {
- win->mapRequestEvent(&e->xmaprequest);
- // if we're using the click to place placement type, then immediately
- // after the window is mapped, we need to start interactively moving it
- if (win->getScreen()->placementPolicy() == BScreen::ClickMousePlacement) {
- int x, y, rx, ry;
- Window c, r;
- unsigned int m;
- XQueryPointer(getXDisplay(), win->getScreen()->getRootWindow(),
- &r, &c, &rx, &ry, &x, &y, &m);
- win->startMove(rx, ry);
- }
- }
- break;
- }
-
- case MapNotify: {
- OpenboxWindow *win = searchWindow(e->xmap.window);
-
- if (win)
- win->mapNotifyEvent(&e->xmap);
-
- break;
- }
-
- case UnmapNotify: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((win = searchWindow(e->xunmap.window))) {
- win->unmapNotifyEvent(&e->xunmap);
- if (focused_window == win)
- focused_window = (OpenboxWindow *) 0;
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xunmap.window))) {
- slit->removeClient(e->xunmap.window);
-#endif // SLIT
-
- }
-
- break;
- }
-
- case DestroyNotify: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((win = searchWindow(e->xdestroywindow.window))) {
- win->destroyNotifyEvent(&e->xdestroywindow);
- if (focused_window == win)
- focused_window = (OpenboxWindow *) 0;
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xdestroywindow.window))) {
- slit->removeClient(e->xdestroywindow.window, False);
-#endif // SLIT
- }
-
- break;
- }
-
- case MotionNotify: {
- // strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
-
- last_time = e->xmotion.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
-
- if ((win = searchWindow(e->xmotion.window)))
- win->motionNotifyEvent(&e->xmotion);
- else if ((menu = searchMenu(e->xmotion.window)))
- menu->motionNotifyEvent(&e->xmotion);
-
- break;
- }
-
- case PropertyNotify: {
- last_time = e->xproperty.time;
-
- if (e->xproperty.state != PropertyDelete) {
- OpenboxWindow *win = searchWindow(e->xproperty.window);
-
- if (win)
- win->propertyNotifyEvent(e->xproperty.atom);
- }
-
- break;
- }
-
- case EnterNotify: {
- last_time = e->xcrossing.time;
-
- BScreen *screen = (BScreen *) 0;
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if (e->xcrossing.mode == NotifyGrab) break;
-
- XEvent dummy;
- scanargs sa;
- sa.w = e->xcrossing.window;
- sa.enter = sa.leave = False;
- XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
-
- if ((e->xcrossing.window == e->xcrossing.root) &&
- (screen = searchScreen(e->xcrossing.window))) {
- screen->getImageControl()->installRootColormap();
- } else if ((win = searchWindow(e->xcrossing.window))) {
- if (win->getScreen()->sloppyFocus() &&
- (! win->isFocused()) && (! no_focus)) {
- grab();
-
- if (((! sa.leave) || sa.inferior) && win->isVisible() &&
- win->setInputFocus())
- win->installColormap(True);
-
- ungrab();
- }
- } else if ((menu = searchMenu(e->xcrossing.window))) {
- menu->enterNotifyEvent(&e->xcrossing);
- } else if ((tbar = searchToolbar(e->xcrossing.window))) {
- tbar->enterNotifyEvent(&e->xcrossing);
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xcrossing.window))) {
- slit->enterNotifyEvent(&e->xcrossing);
-#endif // SLIT
- }
- break;
- }
-
- case LeaveNotify: {
- last_time = e->xcrossing.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((menu = searchMenu(e->xcrossing.window)))
- menu->leaveNotifyEvent(&e->xcrossing);
- else if ((win = searchWindow(e->xcrossing.window)))
- win->installColormap(False);
- else if ((tbar = searchToolbar(e->xcrossing.window)))
- tbar->leaveNotifyEvent(&e->xcrossing);
-#ifdef SLIT
- else if ((slit = searchSlit(e->xcrossing.window)))
- slit->leaveNotifyEvent(&e->xcrossing);
-#endif // SLIT
-
- break;
- }
-
- case Expose: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
- if ((win = searchWindow(e->xexpose.window)))
- win->exposeEvent(&e->xexpose);
- else if ((menu = searchMenu(e->xexpose.window)))
- menu->exposeEvent(&e->xexpose);
- else if ((tbar = searchToolbar(e->xexpose.window)))
- tbar->exposeEvent(&e->xexpose);
-
- break;
- }
-
- case KeyPress: {
- Toolbar *tbar = searchToolbar(e->xkey.window);
-
- if (tbar && tbar->isEditing())
- tbar->keyPressEvent(&e->xkey);
-
- break;
- }
-
- case ColormapNotify: {
- BScreen *screen = searchScreen(e->xcolormap.window);
-
- if (screen)
- screen->setRootColormapInstalled((e->xcolormap.state ==
- ColormapInstalled) ? True : False);
-
- break;
- }
-
- case FocusIn: {
- if (e->xfocus.mode == NotifyUngrab || e->xfocus.detail == NotifyPointer)
- break;
-
- OpenboxWindow *win = searchWindow(e->xfocus.window);
- if (win && ! win->isFocused())
- setFocusedWindow(win);
-
- break;
- }
-
- case FocusOut:
- break;
- case ClientMessage: {
- if (e->xclient.format == 32) {
- if (e->xclient.message_type == getWMChangeStateAtom()) {
- OpenboxWindow *win = searchWindow(e->xclient.window);
- if (! win || ! win->validateClient()) return;
-
- if (e->xclient.data.l[0] == IconicState)
- win->iconify();
- if (e->xclient.data.l[0] == NormalState)
- win->deiconify();
- } else if (e->xclient.message_type == getOpenboxChangeWorkspaceAtom()) {
- BScreen *screen = searchScreen(e->xclient.window);
-
- if (screen && e->xclient.data.l[0] >= 0 &&
- e->xclient.data.l[0] < screen->getWorkspaceCount())
- screen->changeWorkspaceID(e->xclient.data.l[0]);
- } else if (e->xclient.message_type == getOpenboxChangeWindowFocusAtom()) {
- OpenboxWindow *win = searchWindow(e->xclient.window);
-
- if (win && win->isVisible() && win->setInputFocus())
- win->installColormap(True);
- } else if (e->xclient.message_type == getOpenboxCycleWindowFocusAtom()) {
- BScreen *screen = searchScreen(e->xclient.window);
-
- if (screen) {
- if (! e->xclient.data.l[0])
- screen->prevFocus();
- else
- screen->nextFocus();
- }
- } else if (e->xclient.message_type == getOpenboxChangeAttributesAtom()) {
- OpenboxWindow *win = searchWindow(e->xclient.window);
-
- if (win && win->validateClient()) {
- OpenboxHints net;
- net.flags = e->xclient.data.l[0];
- net.attrib = e->xclient.data.l[1];
- net.workspace = e->xclient.data.l[2];
- net.stack = e->xclient.data.l[3];
- net.decoration = e->xclient.data.l[4];
-
- win->changeOpenboxHints(&net);
- }
- }
- }
-
- break;
- }
-
-
- default: {
-#ifdef SHAPE
- if (e->type == getShapeEventBase()) {
- XShapeEvent *shape_event = (XShapeEvent *) e;
- OpenboxWindow *win = (OpenboxWindow *) 0;
+#include <algorithm>
- if ((win = searchWindow(e->xany.window)) ||
- (shape_event->kind != ShapeBounding))
- win->shapeEvent(shape_event);
- }
-#endif // SHAPE
+namespace ob {
- }
- } // switch
-}
+Openbox *Openbox::instance = (Openbox *) 0;
-Bool Openbox::handleSignal(int sig) {
- switch (sig) {
- case SIGHUP:
+void Openbox::signalHandler(int signal)
+{
+ switch (signal) {
case SIGUSR1:
- reconfigure();
+ printf("Caught SIGUSR1 signal. Restarting.\n");
+ instance->restart();
break;
- case SIGUSR2:
- rereadMenu();
- break;
-
- case SIGPIPE:
- case SIGSEGV:
- case SIGFPE:
+ case SIGHUP:
case SIGINT:
case SIGTERM:
- shutdown();
+ case SIGPIPE:
+ printf("Caught signal %d. Exiting.\n", signal);
+ instance->shutdown();
+ break;
- default:
- return False;
+ case SIGFPE:
+ case SIGSEGV:
+ printf("Caught signal %d. Aborting and dumping core.\n", signal);
+ abort();
}
-
- return True;
}
-BScreen *Openbox::searchScreen(Window window) {
- LinkedListIterator<BScreen> it(screenList);
+Openbox::Openbox(int argc, char **argv)
+ : otk::OtkEventDispatcher(),
+ otk::OtkEventHandler()
+{
+ struct sigaction action;
- for (BScreen *curr = it.current(); curr; it++, curr = it.current()) {
- if (curr->getRootWindow() == window) {
- return curr;
- }
- }
+ _state = State_Starting; // initializing everything
- return (BScreen *) 0;
-}
+ Openbox::instance = this;
+ _displayreq = (char*) 0;
+ _argv = argv;
+ _shutdown = false;
+ _restart = false;
+ _rcfilepath = otk::expandTilde("~/.openbox/rc3");
+ _scriptfilepath = otk::expandTilde("~/.openbox/user.py");
+ _focused_client = 0;
+ _sync = false;
-OpenboxWindow *Openbox::searchWindow(Window window) {
- LinkedListIterator<WindowSearch> it(windowSearchList);
+ parseCommandLine(argc, argv);
- for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- return tmp->getData();
- }
- }
-
- return (OpenboxWindow *) 0;
-}
+ // open the X display (and gets some info about it, and its screens)
+ otk::OBDisplay::initialize(_displayreq);
+ assert(otk::OBDisplay::display);
-
-OpenboxWindow *Openbox::searchGroup(Window window, OpenboxWindow *win) {
- OpenboxWindow *w = (OpenboxWindow *) 0;
- LinkedListIterator<WindowSearch> it(groupSearchList);
-
- for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- w = tmp->getData();
- if (w->getClientWindow() != win->getClientWindow())
- return win;
- }
- }
-
- return (OpenboxWindow *) 0;
-}
-
-
-Basemenu *Openbox::searchMenu(Window window) {
- LinkedListIterator<MenuSearch> it(menuSearchList);
-
- for (MenuSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window)
- return tmp->getData();
- }
-
- return (Basemenu *) 0;
-}
-
-
-Toolbar *Openbox::searchToolbar(Window window) {
- LinkedListIterator<ToolbarSearch> it(toolbarSearchList);
-
- for (ToolbarSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window)
- return tmp->getData();
+ XSynchronize(otk::OBDisplay::display, _sync);
+
+ // set up the signal handler
+ action.sa_handler = Openbox::signalHandler;
+ action.sa_mask = sigset_t();
+ action.sa_flags = SA_NOCLDSTOP | SA_NODEFER;
+ sigaction(SIGUSR1, &action, (struct sigaction *) 0);
+ sigaction(SIGPIPE, &action, (struct sigaction *) 0);
+ sigaction(SIGSEGV, &action, (struct sigaction *) 0);
+ sigaction(SIGFPE, &action, (struct sigaction *) 0);
+ sigaction(SIGTERM, &action, (struct sigaction *) 0);
+ sigaction(SIGINT, &action, (struct sigaction *) 0);
+ sigaction(SIGHUP, &action, (struct sigaction *) 0);
+
+ _property = new otk::OBProperty();
+ _actions = new OBActions();
+ _bindings = new OBBindings();
+
+ setMasterHandler(_actions); // set as the master event handler
+
+ // create the mouse cursors we'll use
+ _cursors.session = XCreateFontCursor(otk::OBDisplay::display, XC_left_ptr);
+ _cursors.move = XCreateFontCursor(otk::OBDisplay::display, XC_fleur);
+ _cursors.ll_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ll_angle);
+ _cursors.lr_angle = XCreateFontCursor(otk::OBDisplay::display, XC_lr_angle);
+ _cursors.ul_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ul_angle);
+ _cursors.ur_angle = XCreateFontCursor(otk::OBDisplay::display, XC_ur_angle);
+
+ // initialize scripting
+ python_init(argv[0]);
+
+ // load config values
+ python_exec(SCRIPTDIR"/config.py"); // load openbox config values
+ // run all of the python scripts
+ python_exec(SCRIPTDIR"/builtins.py"); // builtin callbacks
+ // run the user's script or the system defaults if that fails
+ if (!python_exec(_scriptfilepath.c_str()))
+ python_exec(SCRIPTDIR"/defaults.py"); // system default bahaviors
+
+ // initialize all the screens
+ OBScreen *screen;
+ int i = _single ? DefaultScreen(otk::OBDisplay::display) : 0;
+ int max = _single ? i + 1 : ScreenCount(otk::OBDisplay::display);
+ for (; i < max; ++i) {
+ screen = new OBScreen(i);
+ if (screen->managed())
+ _screens.push_back(screen);
+ else
+ delete screen;
}
- return (Toolbar *) 0;
-}
-
-
-#ifdef SLIT
-Slit *Openbox::searchSlit(Window window) {
- LinkedListIterator<SlitSearch> it(slitSearchList);
-
- for (SlitSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window)
- return tmp->getData();
+ if (_screens.empty()) {
+ printf(_("No screens were found without a window manager. Exiting.\n"));
+ ::exit(1);
}
- return (Slit *) 0;
-}
-#endif // SLIT
-
-
-void Openbox::saveWindowSearch(Window window, OpenboxWindow *data) {
- windowSearchList->insert(new WindowSearch(window, data));
-}
-
-
-void Openbox::saveGroupSearch(Window window, OpenboxWindow *data) {
- groupSearchList->insert(new WindowSearch(window, data));
-}
-
-
-void Openbox::saveMenuSearch(Window window, Basemenu *data) {
- menuSearchList->insert(new MenuSearch(window, data));
-}
-
-
-void Openbox::saveToolbarSearch(Window window, Toolbar *data) {
- toolbarSearchList->insert(new ToolbarSearch(window, data));
-}
-
-
-#ifdef SLIT
-void Openbox::saveSlitSearch(Window window, Slit *data) {
- slitSearchList->insert(new SlitSearch(window, data));
-}
-#endif // SLIT
-
-
-void Openbox::removeWindowSearch(Window window) {
- LinkedListIterator<WindowSearch> it(windowSearchList);
- for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- windowSearchList->remove(tmp);
- delete tmp;
- break;
- }
+ ScreenList::iterator it, end = _screens.end();
+ for (it = _screens.begin(); it != end; ++it) {
+ (*it)->manageExisting();
}
-}
+
+ // grab any keys set up before the screens existed
+ _bindings->grabKeys(true);
-
-void Openbox::removeGroupSearch(Window window) {
- LinkedListIterator<WindowSearch> it(groupSearchList);
- for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- groupSearchList->remove(tmp);
- delete tmp;
- break;
- }
- }
+ // set up input focus
+ _focused_screen = _screens[0];
+ setFocusedClient(0);
+
+ _state = State_Normal; // done starting
}
-void Openbox::removeMenuSearch(Window window) {
- LinkedListIterator<MenuSearch> it(menuSearchList);
- for (MenuSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- menuSearchList->remove(tmp);
- delete tmp;
- break;
- }
- }
-}
-
+Openbox::~Openbox()
+{
+ _state = State_Exiting; // time to kill everything
-void Openbox::removeToolbarSearch(Window window) {
- LinkedListIterator<ToolbarSearch> it(toolbarSearchList);
- for (ToolbarSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- toolbarSearchList->remove(tmp);
- delete tmp;
- break;
+ int first_screen = _screens.front()->number();
+
+ std::for_each(_screens.begin(), _screens.end(), otk::PointerAssassin());
+
+ delete _bindings;
+ delete _actions;
+ delete _property;
+
+ python_destroy();
+
+ XSetInputFocus(otk::OBDisplay::display, PointerRoot, RevertToNone,
+ CurrentTime);
+ XSync(otk::OBDisplay::display, false);
+
+ // this tends to block.. i honestly am not sure why. causing an x error in
+ // the shutdown process unblocks it. blackbox simply did a ::exit(0), so
+ // all im gunna do is the same.
+ //otk::OBDisplay::destroy();
+
+ if (_restart) {
+ if (!_restart_prog.empty()) {
+ const std::string &dstr =
+ otk::OBDisplay::screenInfo(first_screen)->displayString();
+ putenv(const_cast<char *>(dstr.c_str()));
+ execlp(_restart_prog.c_str(), _restart_prog.c_str(), NULL);
+ perror(_restart_prog.c_str());
}
- }
-}
-
-
-#ifdef SLIT
-void Openbox::removeSlitSearch(Window window) {
- LinkedListIterator<SlitSearch> it(slitSearchList);
- for (SlitSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
- if (tmp->getWindow() == window) {
- slitSearchList->remove(tmp);
- delete tmp;
- break;
+
+ // fall back in case the above execlp doesn't work
+ execvp(_argv[0], _argv);
+ execvp(otk::basename(_argv[0]).c_str(), _argv);
+ }
+}
+
+
+void Openbox::parseCommandLine(int argc, char **argv)
+{
+ bool err = false;
+
+ for (int i = 1; i < argc; ++i) {
+ std::string arg(argv[i]);
+
+ if (arg == "-display") {
+ if (++i >= argc)
+ err = true;
+ else
+ _displayreq = argv[i];
+ } else if (arg == "-rc") {
+ if (++i >= argc)
+ err = true;
+ else
+ _rcfilepath = argv[i];
+ } else if (arg == "-menu") {
+ if (++i >= argc)
+ err = true;
+ else
+ _menufilepath = argv[i];
+ } else if (arg == "-script") {
+ if (++i >= argc)
+ err = true;
+ else
+ _scriptfilepath = argv[i];
+ } else if (arg == "-sync") {
+ _sync = true;
+ } else if (arg == "-single") {
+ _single = true;
+ } else if (arg == "-version") {
+ showVersion();
+ ::exit(0);
+ } else if (arg == "-help") {
+ showHelp();
+ ::exit(0);
+ } else
+ err = true;
+
+ if (err) {
+ showHelp();
+ exit(1);
}
}
}
-#endif // SLIT
-
-
-void Openbox::restart(const char *prog) {
- shutdown();
-
- if (prog) {
- execlp(prog, prog, NULL);
- perror(prog);
- }
-
- // fall back in case the above execlp doesn't work
- execvp(argv[0], argv);
- execvp(basename(argv[0]), argv);
-}
-
-
-void Openbox::shutdown() {
- BaseDisplay::shutdown();
-
- XSetInputFocus(getXDisplay(), PointerRoot, None, CurrentTime);
-
- LinkedListIterator<BScreen> it(screenList);
- for (BScreen *s = it.current(); s; it++, s = it.current())
- s->shutdown();
-
- XSync(getXDisplay(), False);
-}
-
-
-void Openbox::save() {
- config.setAutoSave(false);
-
- // save all values as they are so that the defaults will be written to the rc
- // file
-
- config.setValue("session.menuFile", getMenuFilename());
- config.setValue("session.colorsPerChannel",
- resource.colors_per_channel);
- config.setValue("session.doubleClickInterval",
- (long)resource.double_click_interval);
- config.setValue("session.autoRaiseDelay",
- ((resource.auto_raise_delay.tv_sec * 1000) +
- (resource.auto_raise_delay.tv_usec / 1000)));
- config.setValue("session.cacheLife", (long)resource.cache_life / 60000);
- config.setValue("session.cacheMax", (long)resource.cache_max);
- config.setValue("session.styleFile", resource.style_file);
-
- LinkedListIterator<BScreen> it(screenList);
- for (BScreen *s = it.current(); s != NULL; it++, s = it.current()) {
- s->save();
- s->getToolbar()->save();
-#ifdef SLIT
- s->getSlit()->save();
-#endif // SLIT
- }
-
- config.setAutoSave(true);
- config.save();
-}
-
-void Openbox::load() {
- if (!config.load())
- config.create();
-
- std::string s;
- long l;
-
- if (resource.menu_file)
- delete [] resource.menu_file;
- if (config.getValue("session.menuFile", "Session.MenuFile", s))
- resource.menu_file = bstrdup(s.c_str());
- else
- resource.menu_file = bstrdup(DEFAULTMENU);
-
- if (config.getValue("session.colorsPerChannel", "Session.ColorsPerChannel",
- l))
- resource.colors_per_channel = (l < 2 ? 2 : (l > 6 ? 6 : l)); // >= 2, <= 6
- else
- resource.colors_per_channel = 4;
-
- if (resource.style_file)
- delete [] resource.style_file;
- if (config.getValue("session.styleFile", "Session.StyleFile", s))
- resource.style_file = bstrdup(s.c_str());
- else
- resource.style_file = bstrdup(DEFAULTSTYLE);
-
- if (resource.titlebar_layout)
- delete [] resource.titlebar_layout;
- if (config.getValue("session.titlebarLayout", "Session.TitlebarLayout", s))
- resource.titlebar_layout = bstrdup(s.c_str());
- else
- resource.titlebar_layout = bstrdup("ILMC");
-
- if (config.getValue("session.doubleClickInterval",
- "Session.DoubleClickInterval", l))
- resource.double_click_interval = l;
- else
- resource.double_click_interval = 250;
-
- if (!config.getValue("session.autoRaiseDelay", "Session.AutoRaiseDelay", l))
- resource.auto_raise_delay.tv_usec = l;
- else
- resource.auto_raise_delay.tv_usec = 400;
- resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec / 1000;
- resource.auto_raise_delay.tv_usec -=
- (resource.auto_raise_delay.tv_sec * 1000);
- resource.auto_raise_delay.tv_usec *= 1000;
-
- if (config.getValue("session.cacheLife", "Session.CacheLife", l))
- resource.cache_life = l;
- else
- resource.cache_life = 51;
- resource.cache_life *= 60000;
-
- if (config.getValue("session.cacheMax", "Session.CacheMax", l))
- resource.cache_max = l;
- else
- resource.cache_max = 200;
-}
-
-void Openbox::reconfigure() {
- reconfigure_wait = True;
- if (! timer->isTiming()) timer->start();
+void Openbox::showVersion()
+{
+ printf(_("Openbox - version %s\n"), VERSION);
+ printf(" (c) 2002 - 2002 Ben Jansens\n\n");
}
-void Openbox::real_reconfigure() {
- grab();
+void Openbox::showHelp()
+{
+ showVersion(); // show the version string and copyright
- load();
-
- for (int i = 0, n = menuTimestamps->count(); i < n; i++) {
- MenuTimestamp *ts = menuTimestamps->remove(0);
+ // print program usage and command line options
+ printf(_("Usage: %s [OPTIONS...]\n\
+ Options:\n\
+ -display <string> use display connection.\n\
+ -single run on a single screen (default is to run every one).\n\
+ -rc <string> use alternate resource file.\n\
+ -menu <string> use alternate menu file.\n\
+ -script <string> use alternate startup script file.\n\
+ -sync run in synchronous mode (for debugging).\n\
+ -version display version and exit.\n\
+ -help display this help text and exit.\n\n"), _argv[0]);
- if (ts) {
- if (ts->filename)
- delete [] ts->filename;
+ printf(_("Compile time options:\n\
+ Debugging: %s\n\
+ Shape: %s\n\
+ Xinerama: %s\n\
+ Xkb: %s\n"),
+#ifdef DEBUG
+ _("yes"),
+#else // !DEBUG
+ _("no"),
+#endif // DEBUG
- delete ts;
- }
- }
+#ifdef SHAPE
+ _("yes"),
+#else // !SHAPE
+ _("no"),
+#endif // SHAPE
- LinkedListIterator<BScreen> it(screenList);
- for (BScreen *screen = it.current(); screen; it++, screen = it.current()) {
- screen->reconfigure();
- }
+#ifdef XINERAMA
+ _("yes"),
+#else // !XINERAMA
+ _("no"),
+#endif // XINERAMA
- ungrab();
+#ifdef XKB
+ _("yes")
+#else // !XKB
+ _("no")
+#endif // XKB
+ );
}
-void Openbox::checkMenu() {
- Bool reread = False;
- LinkedListIterator<MenuTimestamp> it(menuTimestamps);
- for (MenuTimestamp *tmp = it.current(); tmp && (! reread);
- it++, tmp = it.current()) {
- struct stat buf;
-
- if (! stat(tmp->filename, &buf)) {
- if (tmp->timestamp != buf.st_ctime)
- reread = True;
- } else {
- reread = True;
- }
+void Openbox::eventLoop()
+{
+ while (!_shutdown) {
+ _timermanager.fire(!_sync); // wait if not in sync mode
+ dispatchEvents(); // from OtkEventDispatcher
+ XFlush(otk::OBDisplay::display); // flush here before we go wait for timers
}
-
- if (reread) rereadMenu();
}
-void Openbox::rereadMenu() {
- reread_menu_wait = True;
-
- if (! timer->isTiming()) timer->start();
+void Openbox::addClient(Window window, OBClient *client)
+{
+ _clients[window] = client;
}
-void Openbox::real_rereadMenu() {
- for (int i = 0, n = menuTimestamps->count(); i < n; i++) {
- MenuTimestamp *ts = menuTimestamps->remove(0);
-
- if (ts) {
- if (ts->filename)
- delete [] ts->filename;
-
- delete ts;
- }
- }
-
- LinkedListIterator<BScreen> it(screenList);
- for (BScreen *screen = it.current(); screen; it++, screen = it.current())
- screen->rereadMenu();
+void Openbox::removeClient(Window window)
+{
+ _clients.erase(window);
}
-void Openbox::setStyleFilename(const char *filename) {
- if (resource.style_file)
- delete [] resource.style_file;
-
- resource.style_file = bstrdup(filename);
- config.setValue("session.styleFile", resource.style_file);
+OBClient *Openbox::findClient(Window window)
+{
+ /*
+ NOTE: we dont use _clients[] to find the value because that will insert
+ a new null into the hash, which really sucks when we want to clean up the
+ hash at shutdown!
+ */
+ ClientMap::iterator it = _clients.find(window);
+ if (it != _clients.end())
+ return it->second;
+ else
+ return (OBClient*) 0;
}
-void Openbox::setMenuFilename(const char *filename) {
- Bool found = False;
-
- LinkedListIterator<MenuTimestamp> it(menuTimestamps);
- for (MenuTimestamp *tmp = it.current(); tmp && (! found);
- it++, tmp = it.current()) {
- if (! strcmp(tmp->filename, filename)) found = True;
- }
- if (! found) {
- struct stat buf;
-
- if (! stat(filename, &buf)) {
- MenuTimestamp *ts = new MenuTimestamp;
-
- ts->filename = bstrdup(filename);
- ts->timestamp = buf.st_ctime;
-
- menuTimestamps->insert(ts);
+void Openbox::setFocusedClient(OBClient *c)
+{
+ _focused_client = c;
+ if (c) {
+ _focused_screen = _screens[c->screen()];
+ } else {
+ assert(_focused_screen);
+ XSetInputFocus(otk::OBDisplay::display, _focused_screen->focuswindow(),
+ RevertToNone, CurrentTime);
+ }
+ // set the NET_ACTIVE_WINDOW hint for all screens
+ ScreenList::iterator it, end = _screens.end();
+ for (it = _screens.begin(); it != end; ++it) {
+ int num = (*it)->number();
+ Window root = otk::OBDisplay::screenInfo(num)->rootWindow();
+ _property->set(root, otk::OBProperty::net_active_window,
+ otk::OBProperty::Atom_Window,
+ (c && _focused_screen == *it) ? c->window() : None);
+ }
+
+ // call the python Focus callbacks
+ EventData data(_focused_screen->number(), c, EventFocus, 0);
+ Openbox::instance->bindings()->fireEvent(&data);
+}
+
+void Openbox::execute(int screen, const std::string &bin)
+{
+#ifdef __EMX__
+ // XXX: whats this for? windows?
+ spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", bin.c_str(), NULL);
+#else // __EMX__
+ if (screen >= ScreenCount(otk::OBDisplay::display))
+ screen = 0;
+ const std::string &dstr =
+ otk::OBDisplay::screenInfo(screen)->displayString();
+
+ if (! fork()) {
+ setsid();
+ int ret = putenv(const_cast<char *>(dstr.c_str()));
+ assert(ret != -1);
+ ret = execl("/bin/sh", "/bin/sh", "-c", bin.c_str(), NULL);
+ exit(ret);
}
- }
+#endif // __EMX__
}
-
-void Openbox::timeout() {
- if (reconfigure_wait)
- real_reconfigure();
-
- if (reread_menu_wait)
- real_rereadMenu();
-
- reconfigure_wait = reread_menu_wait = False;
}
-
-void Openbox::setFocusedWindow(OpenboxWindow *win) {
- BScreen *old_screen = (BScreen *) 0, *screen = (BScreen *) 0;
- OpenboxWindow *old_win = (OpenboxWindow *) 0;
- Toolbar *old_tbar = (Toolbar *) 0, *tbar = (Toolbar *) 0;
- Workspace *old_wkspc = (Workspace *) 0, *wkspc = (Workspace *) 0;
-
- if (focused_window) {
- 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->getMenu()->setItemSelected(old_win->getWindowNumber(), False);
- }
-
- if (win && ! win->isIconic()) {
- screen = win->getScreen();
- tbar = screen->getToolbar();
- wkspc = screen->getWorkspace(win->getWorkspaceNumber());
-
- focused_window = win;
-
- win->setFocusFlag(True);
- wkspc->getMenu()->setItemSelected(win->getWindowNumber(), True);
- } else {
- focused_window = (OpenboxWindow *) 0;
- }
-
- if (tbar)
- tbar->redrawWindowLabel(True);
- if (screen)
- screen->updateNetizenWindowFocus();
-
- if (old_tbar && old_tbar != tbar)
- old_tbar->redrawWindowLabel(True);
- if (old_screen && old_screen != screen)
- old_screen->updateNetizenWindowFocus();
-}