~ubuntu-branches/ubuntu/trusty/fluxbox/trusty-proposed

« back to all changes in this revision

Viewing changes to src/Screen.cc

  • Committer: Package Import Robot
  • Author(s): Paul Tagliamonte
  • Date: 2010-08-12 21:16:02 UTC
  • mfrom: (0.1.1) (1.1.10)
  • Revision ID: package-import@ubuntu.com-20100812211602-3tsmzl9in5nmwz7z
Tags: 1.1.1+git20100807.0cc08f9-1
* debian/ dir has been cleaned out, complete repackage
  of most files.
* pulled new archive from git.fluxbox.org HEAD, saved as
  tar.gz.
* Added in fluxbox.* files from the old dfsg tree.
* Added in system.fluxbox-menu file from the old dfsg tree
* Added the source/format file to bump package source
  version from 1.0 to 3.0 (quilt). 
* Changed rules file to match the old dfsg setup so that
  fluxbox behaves nicely.
* Removed entries from copyright that no longer apply.
* Added theme based on Denis Brand ( naran )'s old theme.
* Added a background I whipped up.
* Changed compile flags to point to debian theme by default
* Adding a patch to have fluxbox use x-terminal-emulator
  over xterm. Closes: #591694 (LP: #580485)
* Adding a patch to allow titlebar-window dragging.
* Changed the flags in rules to pull from a script. This script
  lets us un-hardcode what theme is default. Be sure there
  is a theme pack!
* Added comments to my patches.
* Removing debian/docs, empty file.
* Fixing fluxbox.desktop to remove all the warnings from
  desktop-file-validate
* Fixing libtool issue by running an update before
  configure in the rules script.
* Added a compile flag script to auto-detect what platform
  we are running on, and apply the correct theme. This
  should solve Ubuntnu issues later on.
* adding in a get-orig-source rule
* fixing the upstream version number to pinpoint
  the commit ( thanks, lfaraone ).
* adding a rule for get-orig-source. ( thanks again,
  lfaraone ).
* Updated rules to actually allow us to do a build from it
* Removed Denis from the uploaders ( as per an email
  conversation )
* Removing madduck from the uploaders ( thanks for asking,
  lfaraone. ). Thanks for your hard work, madduck.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include "FbTk/IntMenuItem.hh"
40
40
#include "FbTk/MenuSeparator.hh"
41
41
#include "FocusModelMenuItem.hh"
42
 
#include "RadioMenuItem.hh"
 
42
#include "FbTk/RadioMenuItem.hh"
43
43
 
44
44
// menus
45
45
#include "FbMenu.hh"
54
54
#include "AtomHandler.hh"
55
55
#include "HeadArea.hh"
56
56
#include "FbCommands.hh"
 
57
#include "Debug.hh"
57
58
 
58
59
#include "FbTk/I18n.hh"
59
60
#include "FbTk/Subject.hh"
154
155
using std::bind2nd;
155
156
using std::equal_to;
156
157
 
157
 
#ifdef DEBUG
158
158
using std::hex;
159
159
using std::dec;
160
 
#endif // DEBUG
161
160
 
162
161
static bool running = true;
163
162
namespace {
176
175
}
177
176
 
178
177
 
 
178
int calcSquareDistance(int x1, int y1, int x2, int y2) {
 
179
    return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
 
180
}
 
181
 
179
182
class TabPlacementMenuItem: public FbTk::RadioMenuItem {
180
183
public:
181
184
    TabPlacementMenuItem(FbTk::FbString & label, BScreen &screen,
206
209
namespace FbTk {
207
210
 
208
211
template<>
209
 
void FbTk::Resource<FbWinFrame::TabPlacement>::
210
 
setFromString(const char *strval) {
211
 
    if (strcasecmp(strval, "TopLeft") == 0)
212
 
        m_value = FbWinFrame::TOPLEFT;
213
 
    else if (strcasecmp(strval, "BottomLeft") == 0)
214
 
        m_value = FbWinFrame::BOTTOMLEFT;
215
 
    else if (strcasecmp(strval, "Top") == 0)
216
 
        m_value = FbWinFrame::TOP;
217
 
    else if (strcasecmp(strval, "Bottom") == 0)
218
 
        m_value = FbWinFrame::BOTTOM;
219
 
    else if (strcasecmp(strval, "TopRight") == 0)
220
 
        m_value = FbWinFrame::TOPRIGHT;
221
 
    else if (strcasecmp(strval, "BottomRight") == 0)
222
 
        m_value = FbWinFrame::BOTTOMRIGHT;
223
 
    else if (strcasecmp(strval, "LeftTop") == 0)
224
 
        m_value = FbWinFrame::LEFTTOP;
225
 
    else if (strcasecmp(strval, "Left") == 0)
226
 
        m_value = FbWinFrame::LEFT;
227
 
    else if (strcasecmp(strval, "LeftBottom") == 0)
228
 
        m_value = FbWinFrame::LEFTBOTTOM;
229
 
    else if (strcasecmp(strval, "RightTop") == 0)
230
 
        m_value = FbWinFrame::RIGHTTOP;
231
 
    else if (strcasecmp(strval, "Right") == 0)
232
 
        m_value = FbWinFrame::RIGHT;
233
 
    else if (strcasecmp(strval, "RightBottom") == 0)
234
 
        m_value = FbWinFrame::RIGHTBOTTOM;
235
 
    else
236
 
        setDefaultValue();
237
 
}
238
 
 
239
 
template<>
240
212
string FbTk::Resource<FbWinFrame::TabPlacement>::
241
213
getString() const {
242
214
    switch (m_value) {
280
252
    //default string
281
253
    return string("TopLeft");
282
254
}
 
255
 
 
256
template<>
 
257
void FbTk::Resource<FbWinFrame::TabPlacement>::
 
258
setFromString(const char *strval) {
 
259
    if (strcasecmp(strval, "TopLeft") == 0)
 
260
        m_value = FbWinFrame::TOPLEFT;
 
261
    else if (strcasecmp(strval, "BottomLeft") == 0)
 
262
        m_value = FbWinFrame::BOTTOMLEFT;
 
263
    else if (strcasecmp(strval, "Top") == 0)
 
264
        m_value = FbWinFrame::TOP;
 
265
    else if (strcasecmp(strval, "Bottom") == 0)
 
266
        m_value = FbWinFrame::BOTTOM;
 
267
    else if (strcasecmp(strval, "TopRight") == 0)
 
268
        m_value = FbWinFrame::TOPRIGHT;
 
269
    else if (strcasecmp(strval, "BottomRight") == 0)
 
270
        m_value = FbWinFrame::BOTTOMRIGHT;
 
271
    else if (strcasecmp(strval, "LeftTop") == 0)
 
272
        m_value = FbWinFrame::LEFTTOP;
 
273
    else if (strcasecmp(strval, "Left") == 0)
 
274
        m_value = FbWinFrame::LEFT;
 
275
    else if (strcasecmp(strval, "LeftBottom") == 0)
 
276
        m_value = FbWinFrame::LEFTBOTTOM;
 
277
    else if (strcasecmp(strval, "RightTop") == 0)
 
278
        m_value = FbWinFrame::RIGHTTOP;
 
279
    else if (strcasecmp(strval, "Right") == 0)
 
280
        m_value = FbWinFrame::RIGHT;
 
281
    else if (strcasecmp(strval, "RightBottom") == 0)
 
282
        m_value = FbWinFrame::RIGHTBOTTOM;
 
283
    else
 
284
        setDefaultValue();
 
285
}
 
286
 
283
287
} // end namespace FbTk
284
288
 
285
289
 
292
296
    max_disable_move(rm, false, scrname+".maxDisableMove", altscrname+".MaxDisableMove"),
293
297
    max_disable_resize(rm, false, scrname+".maxDisableResize", altscrname+".MaxDisableResize"),
294
298
    workspace_warping(rm, true, scrname+".workspacewarping", altscrname+".WorkspaceWarping"),
295
 
    show_window_pos(rm, true, scrname+".showwindowposition", altscrname+".ShowWindowPosition"),
 
299
    show_window_pos(rm, false, scrname+".showwindowposition", altscrname+".ShowWindowPosition"),
296
300
    auto_raise(rm, true, scrname+".autoRaise", altscrname+".AutoRaise"),
297
301
    click_raises(rm, true, scrname+".clickRaises", altscrname+".ClickRaises"),
298
302
    default_deco(rm, "NORMAL", scrname+".defaultDeco", altscrname+".DefaultDeco"),
299
 
    rootcommand(rm, "", scrname+".rootCommand", altscrname+".RootCommand"),
300
303
    tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"),
301
304
    windowmenufile(rm, Fluxbox::instance()->getDefaultDataFilename("windowmenu"), scrname+".windowMenu", altscrname+".WindowMenu"),
302
305
    typing_delay(rm, 0, scrname+".noFocusWhileTypingDelay", altscrname+".NoFocusWhileTypingDelay"),
303
 
    follow_model(rm, SEMIFOLLOW_ACTIVE_WINDOW, scrname+".followModel", altscrname+".followModel"),
304
 
    user_follow_model(rm, SEMIFOLLOW_ACTIVE_WINDOW, scrname+".userFollowModel", altscrname+".UserFollowModel"),
305
306
    workspaces(rm, 4, scrname+".workspaces", altscrname+".Workspaces"),
306
307
    edge_snap_threshold(rm, 10, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
307
308
    focused_alpha(rm, 255, scrname+".window.focus.alpha", altscrname+".Window.Focus.Alpha"),
308
309
    unfocused_alpha(rm, 255, scrname+".window.unfocus.alpha", altscrname+".Window.Unfocus.Alpha"),
309
310
    menu_alpha(rm, 255, scrname+".menu.alpha", altscrname+".Menu.Alpha"),
310
311
    menu_delay(rm, 200, scrname + ".menuDelay", altscrname+".MenuDelay"),
311
 
    menu_delay_close(rm, 200, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
312
312
    tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"),
313
313
    tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"),
314
 
    menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"),
315
 
 
316
 
    gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"),
317
 
    gc_line_style(rm,
318
 
                  FbTk::GContext::LINESOLID,
319
 
                  scrname+".overlay.lineStyle",
320
 
                  altscrname+".Overlay.LineStyle"),
321
 
    gc_join_style(rm,
322
 
                  FbTk::GContext::JOINMITER,
323
 
                  scrname+".overlay.joinStyle",
324
 
                  altscrname+".Overlay.JoinStyle"),
325
 
    gc_cap_style(rm,
326
 
                 FbTk::GContext::CAPNOTLAST,
327
 
                 scrname+".overlay.capStyle",
328
 
                 altscrname+".overlay.CapStyle"),
329
314
    allow_remote_actions(rm, false, scrname+".allowRemoteActions", altscrname+".AllowRemoteActions"),
330
315
    clientmenu_use_pixmap(rm, true, scrname+".clientMenu.usePixmap", altscrname+".ClientMenu.UsePixmap"),
331
316
    tabs_use_pixmap(rm, true, scrname+".tabs.usePixmap", altscrname+".Tabs.UsePixmap"),
339
324
                 const string &screenname,
340
325
                 const string &altscreenname,
341
326
                 int scrn, int num_layers) :
342
 
    m_clientlist_sig(*this),  // client signal
343
 
    m_iconlist_sig(*this), // icon list signal
344
 
    m_workspacecount_sig(*this), // workspace count signal
345
 
    m_workspacenames_sig(*this), // workspace names signal
346
 
    m_workspace_area_sig(*this), // workspace area signal
347
 
    m_currentworkspace_sig(*this), // current workspace signal
348
 
    m_focusedwindow_sig(*this), // focused window signal
349
327
    m_reconfigure_sig(*this), // reconfigure signal
350
 
    m_resize_sig(*this),
351
 
    m_bg_change_sig(*this),
352
328
    m_layermanager(num_layers),
353
329
    m_focused_windowtheme(new FbWinFrameTheme(scrn, ".focus", ".Focus")),
354
330
    m_unfocused_windowtheme(new FbWinFrameTheme(scrn, ".unfocus", ".Unfocus")),
470
446
    imageControl().installRootColormap();
471
447
    root_colormap_installed = true;
472
448
 
473
 
    // if user specified background in the config then use it
474
 
    if (!resource.rootcommand->empty()) {
475
 
        FbCommands::ExecuteCmd cmd(*resource.rootcommand, screenNumber());
476
 
        cmd.execute();
477
 
    }
478
 
 
479
449
    m_root_theme.reset(new RootTheme(imageControl()));
480
450
    m_root_theme->reconfigTheme();
481
451
 
482
452
    focusedWinFrameTheme()->setAlpha(*resource.focused_alpha);
483
453
    unfocusedWinFrameTheme()->setAlpha(*resource.unfocused_alpha);
484
454
    m_menutheme->setAlpha(*resource.menu_alpha);
485
 
    m_menutheme->setMenuMode(*resource.menu_mode);
486
455
    // clamp values
487
456
    if (*resource.menu_delay > 5000)
488
457
        *resource.menu_delay = 5000;
489
458
    if (*resource.menu_delay < 0)
490
459
        *resource.menu_delay = 0;
491
460
 
492
 
    if (*resource.menu_delay_close > 5000)
493
 
        *resource.menu_delay_close = 5000;
494
 
    if (*resource.menu_delay_close < 0)
495
 
        *resource.menu_delay_close = 0;
496
 
 
497
 
    m_menutheme->setDelayOpen(*resource.menu_delay);
498
 
    m_menutheme->setDelayClose(*resource.menu_delay_close);
 
461
    m_menutheme->setDelay(*resource.menu_delay);
499
462
 
500
463
    focusedWinFrameTheme()->reconfigSig().attach(this);// for geom window
501
464
 
548
511
 
549
512
    changeWorkspaceID(first_desktop);
550
513
 
551
 
    // we need to load win frame theme before we create any fluxbox window
552
 
    // and after we've load the resources
553
 
    // else we get some bad handle/grip height/width
554
 
    //    FbTk::ThemeManager::instance().loadTheme(*m_windowtheme.get());
555
 
    m_root_theme->setLineAttributes(*resource.gc_line_width,
556
 
                                    *resource.gc_line_style,
557
 
                                    *resource.gc_cap_style,
558
 
                                    *resource.gc_join_style);
559
 
 
560
514
#ifdef SLIT
561
515
    m_slit.reset(new Slit(*this, *layerManager().getLayer(Layer::DESKTOP),
562
516
                 fluxbox->getSlitlistFilename().c_str()));
681
635
                (wmhints->icon_window != children[i]))
682
636
                for (unsigned int j = 0; j < nchild; j++) {
683
637
                    if (children[j] == wmhints->icon_window) {
684
 
#ifdef DEBUG
685
 
                        cerr<<"BScreen::initWindows(): children[j] = 0x"<<hex<<children[j]<<dec<<endl;
686
 
                        cerr<<"BScreen::initWindows(): = icon_window"<<endl;
687
 
#endif // DEBUG
 
638
 
 
639
                        fbdbg<<"BScreen::initWindows(): children[j] = 0x"<<hex<<children[j]<<dec<<endl;
 
640
                        fbdbg<<"BScreen::initWindows(): = icon_window"<<endl;
 
641
 
688
642
                        children[j] = None;
689
643
                        break;
690
644
                    }
714
668
        if (children[i] == None)
715
669
            continue;
716
670
        else if (!fluxbox->validateWindow(children[i])) {
717
 
#ifdef DEBUG
718
 
            cerr<<"BScreen::initWindows(): not valid window = "<<hex<<children[i]<<dec<<endl;
719
 
#endif // DEBUG
 
671
 
 
672
            fbdbg<<"BScreen::initWindows(): not valid window = "<<hex<<children[i]<<dec<<endl;
 
673
 
720
674
            children[i] = None;
721
675
            continue;
722
676
        }
729
683
            children[num_transients] = children[i];
730
684
            num_transients++;
731
685
 
732
 
#ifdef DEBUG
733
 
            cerr<<"BScreen::initWindows(): postpone creation of 0x"<<hex<<children[i]<<dec<<endl;
734
 
            cerr<<"BScreen::initWindows(): transient_for = 0x"<<hex<<transient_for<<dec<<endl;
735
 
#endif // DEBUG
 
686
            fbdbg<<"BScreen::initWindows(): postpone creation of 0x"<<hex<<children[i]<<dec<<endl;
 
687
            fbdbg<<"BScreen::initWindows(): transient_for = 0x"<<hex<<transient_for<<dec<<endl;
 
688
 
736
689
            continue;
737
690
        }
738
691
 
850
803
                    &ret_bytes_after, (unsigned char **)&str);
851
804
            }
852
805
 
853
 
            FbTk::RefCount<FbTk::Command<void> > cmd(FbTk::CommandParser<void>::instance().parse(str, false));
 
806
            static std::auto_ptr<FbTk::Command<void> > cmd(0);
 
807
            cmd.reset(FbTk::CommandParser<void>::instance().parse(str, false));
854
808
            if (cmd.get())
855
809
                cmd->execute();
856
810
            XFree(str);
858
812
        }
859
813
    // TODO: this doesn't belong in FbPixmap
860
814
    } else if (FbTk::FbPixmap::rootwinPropertyNotify(screenNumber(), atom))
861
 
        m_bg_change_sig.notify();
 
815
        m_bg_change_sig.emit(*this);
862
816
}
863
817
 
864
818
void BScreen::keyPressEvent(XKeyEvent &ke) {
865
 
    Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode,
866
 
                                          Keys::GLOBAL|Keys::ON_DESKTOP);
 
819
    if (Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode,
 
820
                                              Keys::GLOBAL|Keys::ON_DESKTOP))
 
821
        // re-grab keyboard, so we don't pass KeyRelease to clients
 
822
        // also for catching invalid keys in the middle of keychains
 
823
        FbTk::EventManager::instance()->grabKeyboard(rootWindow().window());
 
824
 
867
825
}
868
826
 
869
827
void BScreen::keyReleaseEvent(XKeyEvent &ke) {
870
 
    if (!m_cycling)
871
 
        return;
872
 
 
873
 
    unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state);
874
 
    state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode);
875
 
 
876
 
    if (!state) // all modifiers were released
 
828
    if (m_cycling) {
 
829
        unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state);
 
830
        state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode);
 
831
 
 
832
        if (state) // still cycling
 
833
            return;
 
834
 
 
835
        m_cycling = false;
 
836
        focusControl().stopCyclingFocus();
 
837
    }
 
838
    if (!Fluxbox::instance()->keys()->inKeychain())
877
839
        FbTk::EventManager::instance()->ungrabKeyboard();
878
840
}
879
841
 
886
848
                   0, be.time);
887
849
}
888
850
 
889
 
void BScreen::notifyUngrabKeyboard() {
890
 
    m_cycling = false;
891
 
    focusControl().stopCyclingFocus();
892
 
}
893
 
 
894
851
void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
895
852
    // get modifiers from event that causes this for focus order cycling
896
853
    XEvent ev = Fluxbox::instance()->lastEvent();
902
859
 
903
860
    if (!m_cycling && mods) {
904
861
        m_cycling = true;
905
 
        FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window());
 
862
        FbTk::EventManager::instance()->grabKeyboard(rootWindow().window());
906
863
    }
907
864
 
908
865
    if (mods == 0) // can't stacked cycle unless there is a mod to grab
947
904
    focusedWinFrameTheme()->setAlpha(*resource.focused_alpha);
948
905
    unfocusedWinFrameTheme()->setAlpha(*resource.unfocused_alpha);
949
906
    m_menutheme->setAlpha(*resource.menu_alpha);
950
 
    m_menutheme->setMenuMode(*resource.menu_mode);
951
907
 
952
908
    // clamp values
953
909
    if (*resource.menu_delay > 5000)
955
911
    if (*resource.menu_delay < 0)
956
912
        *resource.menu_delay = 0;
957
913
 
958
 
    if (*resource.menu_delay_close > 5000)
959
 
        *resource.menu_delay_close = 5000;
960
 
    if (*resource.menu_delay_close < 0)
961
 
        *resource.menu_delay_close = 0;
962
 
 
963
 
    m_root_theme->setLineAttributes(*resource.gc_line_width,
964
 
                                    *resource.gc_line_style,
965
 
                                    *resource.gc_cap_style,
966
 
                                    *resource.gc_join_style);
967
 
 
968
 
    m_menutheme->setDelayOpen(*resource.menu_delay);
969
 
    m_menutheme->setDelayClose(*resource.menu_delay_close);
 
914
    m_menutheme->setDelay(*resource.menu_delay);
970
915
 
971
916
    // realize the number of workspaces from the init-file
972
917
    const unsigned int nr_ws = *resource.workspaces;
1019
964
    Workspace *space = getWorkspace(w);
1020
965
    if (space) {
1021
966
        m_workspace_names[w] = space->name();
1022
 
        m_workspacenames_sig.notify();
 
967
        m_workspacenames_sig.emit(*this);
1023
968
        Fluxbox::instance()->save_rc();
1024
969
    }
1025
970
}
1036
981
    if (find(iconList().begin(), iconList().end(), w) != iconList().end())
1037
982
        return;
1038
983
 
1039
 
    m_icon_list.push_back(w);
 
984
    iconList().push_back(w);
1040
985
 
1041
986
    // notify listeners
1042
 
    m_iconlist_sig.notify();
 
987
    iconListSig().emit(*this);
1043
988
}
1044
989
 
1045
990
 
1054
999
    // change the iconlist
1055
1000
    if (erase_it != m_icon_list.end()) {
1056
1001
        iconList().erase(erase_it);
1057
 
        m_iconlist_sig.notify();
 
1002
        iconListSig().emit(*this);
1058
1003
    }
1059
1004
}
1060
1005
 
1061
1006
void BScreen::removeWindow(FluxboxWindow *win) {
1062
 
#ifdef DEBUG
1063
 
    cerr<<"BScreen::removeWindow("<<win<<")"<<endl;
1064
 
#endif // DEBUG
 
1007
 
 
1008
    fbdbg<<"BScreen::removeWindow("<<win<<")"<<endl;
 
1009
 
1065
1010
    // extra precaution, if for some reason, the
1066
1011
    // icon list should be out of sync
1067
1012
    removeIcon(win);
1077
1022
    focusControl().removeClient(client);
1078
1023
 
1079
1024
    if (client.fbwindow() && client.fbwindow()->isIconic())
1080
 
        iconListSig().notify();
 
1025
        iconListSig().emit(*this);
1081
1026
 
1082
1027
    using namespace FbTk;
1083
1028
 
1106
1051
 
1107
1052
    if (save_name) {
1108
1053
        addWorkspaceName(wkspc->name().c_str()); //update names
1109
 
        m_workspacenames_sig.notify();
 
1054
        m_workspacenames_sig.emit(*this);
1110
1055
    }
1111
1056
 
1112
1057
    saveWorkspaces(m_workspaces_list.size());
1113
 
    workspaceCountSig().notify();
 
1058
    workspaceCountSig().emit( *this );
1114
1059
 
1115
1060
    return m_workspaces_list.size();
1116
1061
 
1134
1079
        if ((*it)->workspaceNumber() == wkspc->workspaceID())
1135
1080
            (*it)->setWorkspace(wkspc->workspaceID()-1);
1136
1081
    }
1137
 
    m_clientlist_sig.notify();
 
1082
    m_clientlist_sig.emit(*this);
1138
1083
 
1139
1084
    //remove last workspace
1140
1085
    m_workspaces_list.pop_back();
1141
1086
 
1142
1087
    saveWorkspaces(m_workspaces_list.size());
1143
 
    workspaceCountSig().notify();
 
1088
    workspaceCountSig().emit( *this );
1144
1089
    // must be deleted after we send notify!!
1145
1090
    // so we dont get bad pointers somewhere
1146
1091
    // while processing the notify signal
1156
1101
        id == m_current_workspace->workspaceID())
1157
1102
        return;
1158
1103
 
 
1104
    /* Ignore all EnterNotify events until the pointer actually moves */
 
1105
    this->focusControl().ignoreAtPointer();
 
1106
 
1159
1107
    FbTk::App::instance()->sync(false);
1160
1108
 
 
1109
    FluxboxWindow *focused = FocusControl::focusedFbWindow();
 
1110
 
 
1111
    if (focused && focused->isMoving() && doOpaqueMove())
 
1112
        // don't reassociate if not opaque moving
 
1113
        reassociateWindow(focused, id, true);
 
1114
 
1161
1115
    // set new workspace
1162
1116
    Workspace *old = currentWorkspace();
1163
1117
    m_current_workspace = getWorkspace(id);
1165
1119
    // we show new workspace first in order to appear faster
1166
1120
    currentWorkspace()->showAll();
1167
1121
 
1168
 
    FluxboxWindow *focused = FocusControl::focusedFbWindow();
1169
 
 
1170
 
    if (focused && focused->isMoving()) {
1171
 
        if (doOpaqueMove())
1172
 
            reassociateWindow(focused, id, true);
1173
 
        // don't reassociate if not opaque moving
1174
 
        focused->pauseMoving();
1175
 
    }
1176
 
 
1177
1122
    // reassociate all windows that are stuck to the new workspace
1178
1123
    Workspace::Windows wins = old->windowList();
1179
1124
    Workspace::Windows::iterator it = wins.begin();
1190
1135
            (*icon_it)->setWorkspace(id);
1191
1136
    }
1192
1137
 
1193
 
    if (focused && focused->isMoving()) {
 
1138
    if (focused && focused->isMoving() && doOpaqueMove())
1194
1139
        focused->focus();
1195
 
        focused->resumeMoving();
1196
 
    } else if (revert)
 
1140
    else if (revert)
1197
1141
        FocusControl::revertFocus(*this);
1198
1142
 
1199
1143
    old->hideAll(false);
1200
1144
 
1201
1145
    FbTk::App::instance()->sync(false);
1202
1146
 
1203
 
    m_currentworkspace_sig.notify();
 
1147
    m_currentworkspace_sig.emit(*this);
1204
1148
 
1205
1149
    // do this after atom handlers, so scripts can access new workspace number
1206
1150
    Fluxbox::instance()->keys()->doAction(FocusIn, 0, 0, Keys::ON_DESKTOP);
1290
1234
bool BScreen::addKdeDockapp(Window client) {
1291
1235
 
1292
1236
    XSelectInput(FbTk::App::instance()->display(), client, StructureNotifyMask);
1293
 
    char intbuff[16];
1294
 
    sprintf(intbuff, "%d", screenNumber());
1295
1237
    string atom_name("_NET_SYSTEM_TRAY_S");
1296
 
    atom_name += intbuff; // append number
 
1238
    atom_name += FbTk::StringUtil::number2String(screenNumber());
1297
1239
    // find the right atomhandler that has the name: _NET_SYSTEM_TRAY_S<num>
1298
1240
    AtomHandler *handler = Fluxbox::instance()->getAtomHandler(atom_name);
1299
1241
    FbTk::EventHandler *evh  = 0;
1377
1319
    else if (other) // should never happen
1378
1320
        win->moveClientRightOf(*other, *winclient);
1379
1321
 
1380
 
    m_clientlist_sig.notify();
 
1322
    m_clientlist_sig.emit(*this);
1381
1323
 
1382
1324
    FbTk::App::instance()->sync(false);
1383
1325
    return win;
1411
1353
            && win->focus())
1412
1354
        FocusControl::setFocusedWindow(&client);
1413
1355
 
1414
 
    m_clientlist_sig.notify();
 
1356
    m_clientlist_sig.emit(*this);
1415
1357
 
1416
1358
    return win;
1417
1359
}
1458
1400
    }
1459
1401
 
1460
1402
    if (updated)
1461
 
        m_workspace_area_sig.notify();
 
1403
        m_workspace_area_sig.emit(*this);
1462
1404
}
1463
1405
 
1464
1406
void BScreen::addWorkspaceName(const char *name) {
1563
1505
    if (erase_it != m_configmenu_list.end())
1564
1506
        m_configmenu_list.erase(erase_it);
1565
1507
 
1566
 
    setupConfigmenu(*m_configmenu.get());
 
1508
    if (!isShuttingdown())
 
1509
        setupConfigmenu(*m_configmenu.get());
1567
1510
 
1568
1511
}
1569
1512
 
1612
1555
               "Click To Focus", "Click to focus",
1613
1556
               FocusControl::CLICKFOCUS);
1614
1557
    _FOCUSITEM(Configmenu, MouseFocus,
1615
 
               "Mouse Focus", "Mouse Focus",
 
1558
               "Mouse Focus (Keyboard Friendly)",
 
1559
               "Mouse Focus (Keyboard Friendly)",
1616
1560
               FocusControl::MOUSEFOCUS);
 
1561
    _FOCUSITEM(Configmenu, StrictMouseFocus,
 
1562
               "Mouse Focus (Strict)",
 
1563
               "Mouse Focus (Strict)",
 
1564
               FocusControl::STRICTMOUSEFOCUS);
1617
1565
#undef _FOCUSITEM
1618
1566
 
1619
1567
    focus_menu->insert(new FbTk::MenuSeparator());
1634
1582
        cerr<<e.what()<<endl;
1635
1583
    }
1636
1584
 
1637
 
    focus_menu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu,
1638
 
                                                AutoRaise,
1639
 
                                                "Auto Raise",
1640
 
                                                "Auto Raise windows on sloppy"),
1641
 
                                        resource.auto_raise,
1642
 
                                        save_and_reconfigure));
 
1585
    _BOOLITEM(*focus_menu, Configmenu, AutoRaise,
 
1586
              "Auto Raise", "Auto Raise windows on sloppy",
 
1587
              resource.auto_raise, saverc_cmd);
 
1588
    _BOOLITEM(*focus_menu, Configmenu, ClickRaises,
 
1589
              "Click Raises", "Click Raises",
 
1590
              resource.click_raises, saverc_cmd);
1643
1591
 
1644
1592
    focus_menu->updateMenu();
1645
1593
 
1806
1754
              "Workspace Warping",
1807
1755
              "Workspace Warping - dragging windows to the edge and onto the next workspace",
1808
1756
              resource.workspace_warping, saverc_cmd);
1809
 
    _BOOLITEM(menu, Configmenu, ClickRaises,
1810
 
              "Click Raises", "Click Raises",
1811
 
              resource.click_raises, saverc_cmd);
1812
1757
 
1813
1758
#undef _BOOLITEM
1814
1759
 
1932
1877
    // update xinerama layout
1933
1878
    initXinerama();
1934
1879
 
1935
 
    // force update geometry
1936
 
    rootWindow().updateGeometry();
1937
 
 
1938
 
    // reset background
1939
 
    m_root_theme->reconfigTheme();
1940
 
 
1941
 
    // send resize notify
1942
 
    m_resize_sig.notify();
1943
 
    m_workspace_area_sig.notify();
1944
 
 
1945
 
    // move windows out of inactive heads
1946
 
    clearHeads();
 
1880
    // check if window geometry has changed
 
1881
    if (rootWindow().updateGeometry()) {
 
1882
        // reset background
 
1883
        m_root_theme->reset();
 
1884
 
 
1885
        // send resize notify
 
1886
        m_resize_sig.emit(*this);
 
1887
        m_workspace_area_sig.emit(*this);
 
1888
 
 
1889
        // move windows out of inactive heads
 
1890
        clearHeads();
 
1891
    }
1947
1892
}
1948
1893
 
1949
1894
 
1985
1930
    return other;
1986
1931
}
1987
1932
void BScreen::clearXinerama() {
1988
 
#ifdef DEBUG
1989
 
    cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
1990
 
#endif // DEBUG
 
1933
    fbdbg<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
 
1934
 
1991
1935
    m_xinerama_avail = false;
1992
1936
    if (m_xinerama_headinfo)
1993
1937
        delete [] m_xinerama_headinfo;
2003
1947
        clearXinerama();
2004
1948
        return;
2005
1949
    }
2006
 
#ifdef DEBUG
2007
 
    cerr<<"BScreen::initXinerama(): have Xinerama"<<endl;
2008
 
#endif // DEBUG
 
1950
 
 
1951
    fbdbg<<"BScreen::initXinerama(): have Xinerama"<<endl;
 
1952
 
2009
1953
    m_xinerama_avail = true;
2010
1954
 
2011
1955
    XineramaScreenInfo *screen_info;
2023
1967
 
2024
1968
    if (m_xinerama_headinfo)
2025
1969
        delete [] m_xinerama_headinfo;
 
1970
 
2026
1971
    m_xinerama_headinfo = new XineramaHeadInfo[number];
2027
1972
    m_xinerama_num_heads = number;
2028
1973
    for (int i=0; i < number; i++) {
2032
1977
        m_xinerama_headinfo[i].height = screen_info[i].height;
2033
1978
    }
2034
1979
    XFree(screen_info);
2035
 
#ifdef DEBUG
2036
 
    cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
2037
 
#endif // DEBUG
 
1980
 
 
1981
    fbdbg<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
2038
1982
 
2039
1983
    /* Reallocate to the new number of heads. */
2040
 
    int ha_num = numHeads() ? numHeads() : 1, ha_oldnum = m_head_areas.size();
 
1984
    int ha_num = numHeads() ? numHeads() : 1;
 
1985
    int ha_oldnum = m_head_areas.size();
2041
1986
    if (ha_num > ha_oldnum) {
2042
1987
        m_head_areas.resize(ha_num);
2043
1988
        for (int i = ha_oldnum; i < ha_num; i++)
2061
2006
    if (!hasXinerama()) return;
2062
2007
 
2063
2008
    for (Workspaces::iterator i = m_workspaces_list.begin();
2064
 
            i != m_workspaces_list.end(); i++) {
2065
 
        for (Workspace::Windows::iterator win = (*i)->windowList().begin();
2066
 
                win != (*i)->windowList().end(); win++) {
2067
 
            if (getHead((*win)->fbWindow()) == 0) {
2068
 
                // first head is a safe bet here
2069
 
                (*win)->placeWindow(1);
 
2009
            i != m_workspaces_list.end(); i++) {
 
2010
        for (Workspace::Windows::iterator win = (*i)->windowList().begin();
 
2011
                win != (*i)->windowList().end(); win++) {
 
2012
 
 
2013
            int closest_head = getHead((*win)->fbWindow());
 
2014
            if (closest_head == 0) {
 
2015
                closest_head = 1; // first head is a safe bet here
2070
2016
            }
2071
 
        }
 
2017
            (*win)->placeWindow(closest_head);
 
2018
        }
2072
2019
    }
2073
2020
}
2074
2021
 
2075
2022
int BScreen::getHead(int x, int y) const {
2076
 
    if (!hasXinerama()) return 0;
 
2023
 
2077
2024
#ifdef XINERAMA
2078
 
 
2079
 
    for (int i=0; i < m_xinerama_num_heads; i++) {
2080
 
        if (x >= m_xinerama_headinfo[i].x &&
2081
 
            x < (m_xinerama_headinfo[i].x + m_xinerama_headinfo[i].width) &&
2082
 
            y >= m_xinerama_headinfo[i].y &&
2083
 
            y < (m_xinerama_headinfo[i].y + m_xinerama_headinfo[i].height)) {
2084
 
            return i+1;
 
2025
    if (hasXinerama()) {
 
2026
        for (int i=0; i < m_xinerama_num_heads; i++) {
 
2027
            if (x >= m_xinerama_headinfo[i].x &&
 
2028
                    x < (m_xinerama_headinfo[i].x + m_xinerama_headinfo[i].width) &&
 
2029
                    y >= m_xinerama_headinfo[i].y &&
 
2030
                    y < (m_xinerama_headinfo[i].y + m_xinerama_headinfo[i].height)) {
 
2031
                return i+1;
 
2032
            }
2085
2033
        }
2086
2034
    }
2087
 
 
2088
2035
#endif // XINERAMA
2089
2036
    return 0;
2090
2037
}
2091
2038
 
 
2039
 
2092
2040
int BScreen::getHead(const FbTk::FbWindow &win) const {
2093
 
    if (hasXinerama())
2094
 
        return getHead(win.x() + win.width()/2, win.y() + win.height()/2);
2095
 
    else
2096
 
        return 0;
 
2041
 
 
2042
    int head = 0; // whole screen
 
2043
 
 
2044
#if XINERAMA
 
2045
    if (hasXinerama()) {
 
2046
 
 
2047
        // cast needed to prevent win.x() become "unsigned int" which is bad
 
2048
        // since it might become negative
 
2049
        int cx = win.x() + static_cast<int>(win.width() / 2);
 
2050
        int cy = win.y() + static_cast<int>(win.height() / 2);
 
2051
 
 
2052
        long dist = -1;
 
2053
 
 
2054
        int i;
 
2055
        for (i = 0; i < m_xinerama_num_heads; ++i) {
 
2056
 
 
2057
            XineramaHeadInfo& hi = m_xinerama_headinfo[i];
 
2058
            int d = calcSquareDistance(cx, cy, hi.x + (hi.width / 2), hi.y + (hi.height / 2));
 
2059
 
 
2060
            if (dist == -1 || d < dist) { // found a closer head
 
2061
                head = i + 1;
 
2062
                dist = d;
 
2063
            }
 
2064
        }
 
2065
    }
 
2066
#endif
 
2067
 
 
2068
    return head;
2097
2069
}
2098
2070
 
2099
2071
 
2155
2127
    // if there are multiple heads, head=0 is not valid
2156
2128
    // a better way would be to search the closest head
2157
2129
    if (head == 0 && numHeads() != 0)
2158
 
        head = 1;
 
2130
        head = 1;
2159
2131
 
2160
2132
    int hx = getHeadX(head);
2161
2133
    int hy = getHeadY(head);