~ctwm/ctwm/trunk

« back to all changes in this revision

Viewing changes to occupation.c

  • Committer: Matthew Fuller
  • Date: 2016-07-27 11:35:34 UTC
  • mto: This revision was merged to the branch mainline in revision 505.
  • Revision ID: fullermd@over-yonder.net-20160727113534-eapehet7n0ckuyah
Comment another block of functions.  Do some minor code rearrangement
along the way; no functional change.

Show diffs side-by-side

added added

removed removed

Lines of Context:
552
552
}
553
553
 
554
554
 
 
555
/* f.toggleoccupation - flip setting for [current] workspace */
555
556
void
556
557
ToggleOccupation(char *wname, TwmWindow *twm_win)
557
558
{
568
569
 
569
570
        newoccupation = twm_win->occupation ^ (1 << ws->number);
570
571
        if(!newoccupation) {
 
572
                /* Don't allow de-occupying _every_ ws */
571
573
                return;
572
574
        }
573
575
        ChangeOccupation(twm_win, newoccupation);
574
576
}
575
577
 
576
578
 
 
579
/* f.movetonextworkspace */
577
580
void
578
581
MoveToNextWorkSpace(VirtualScreen *vs, TwmWindow *twm_win)
579
582
{
588
591
        wlist2 = wlist1->next;
589
592
        wlist2 = wlist2 ? wlist2 : Scr->workSpaceMgr.workSpaceList;
590
593
 
 
594
        /* Out of (here), into (here+1) */
591
595
        newoccupation = (twm_win->occupation ^ (1 << wlist1->number))
592
596
                        | (1 << wlist2->number);
593
597
        ChangeOccupation(twm_win, newoccupation);
594
598
}
595
599
 
596
600
 
 
601
/* f.movetonextworkspaceandfollow */
597
602
void
598
603
MoveToNextWorkSpaceAndFollow(VirtualScreen *vs, TwmWindow *twm_win)
599
604
{
609
614
}
610
615
 
611
616
 
 
617
/* f.movetoprevworkspaceand */
612
618
void
613
619
MoveToPrevWorkSpace(VirtualScreen *vs, TwmWindow *twm_win)
614
620
{
629
635
                wlist1 = wlist1->next;
630
636
        }
631
637
 
 
638
        /* Out of (here), into (here-1) */
632
639
        newoccupation = (twm_win->occupation ^ (1 << wlist2->number))
633
640
                        | (1 << wlist1->number);
634
641
        ChangeOccupation(twm_win, newoccupation);
635
642
}
636
643
 
637
644
 
 
645
/* f.movetoprevworkspaceandfollow */
638
646
void
639
647
MoveToPrevWorkSpaceAndFollow(VirtualScreen *vs, TwmWindow *twm_win)
640
648
{
650
658
}
651
659
 
652
660
 
 
661
/*
 
662
 * The actual meat of occupation-changing; [re-]set the occupation for
 
663
 * the window.
 
664
 */
653
665
void
654
666
ChangeOccupation(TwmWindow *tmp_win, int newoccupation)
655
667
{
656
668
        TwmWindow *t;
657
669
        WorkSpace *ws;
658
670
        int oldoccupation;
659
 
        long eventMask;
660
671
        int changedoccupation;
661
672
 
662
673
        if((newoccupation == 0)
663
 
                        ||  /* in case the property has been broken by another client */
664
 
                        (newoccupation == tmp_win->occupation)) {
 
674
                        || (newoccupation == tmp_win->occupation)) {
 
675
                /*
 
676
                 * occupation=0 we interpret as "leave it alone".  == current,
 
677
                 * ditto.  Go ahead and re-set the WM_OCCUPATION property though,
 
678
                 * in case it's been broken by another client.
 
679
                 */
665
680
                char *namelist;
666
681
                int  len;
667
682
                XWindowAttributes winattrs;
 
683
                long eventMask;
668
684
 
 
685
                /* Mask out the PropertyChange events while we change the prop */
669
686
                XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
670
687
                eventMask = winattrs.your_event_mask;
671
688
                XSelectInput(dpy, tmp_win->w, eventMask & ~PropertyChangeMask);
677
694
#ifdef EWMH
678
695
                EwmhSet_NET_WM_DESKTOP(tmp_win);
679
696
#endif
 
697
 
 
698
                /* Reset event mask */
680
699
                XSelectInput(dpy, tmp_win->w, eventMask);
681
700
                return;
682
701
        }
 
702
 
 
703
        /*
 
704
         * OK, there's something to change.  Stash the current state.
 
705
         */
683
706
        oldoccupation = tmp_win->occupation;
 
707
 
 
708
        /*
 
709
         * Add it to IconManager in the new WS[en], remove from old.  We have
 
710
         * to do the rather odd dance because AddIconManager() loops through
 
711
         * workspaces, and will add it to any workspaces it occupies (even if
 
712
         * it's already there).  RemoveIconManager() goes over the window's
 
713
         * list of what icon managers it's on and removes it from any that
 
714
         * don't match the current occupation, so it can just be told "here's
 
715
         * where I should be".
 
716
         */
684
717
        tmp_win->occupation = newoccupation & ~oldoccupation;
685
718
        AddIconManager(tmp_win);
686
719
        tmp_win->occupation = newoccupation;
687
720
        RemoveIconManager(tmp_win);
688
721
 
 
722
        /* If it shouldn't be "here", vanish it */
689
723
        if(tmp_win->vs && !OCCUPY(tmp_win, tmp_win->vs->wsw->currentwspc)) {
690
724
                Vanish(tmp_win->vs, tmp_win);
691
725
        }
 
726
 
692
727
        /*
693
728
         * Try to find an(other) virtual screen which shows a workspace
694
729
         * where the window has occupation, so that the window can be shown
704
739
                }
705
740
        }
706
741
 
 
742
        /*
 
743
         * Loop over workspaces.  Find the first one that it used to be in.
 
744
         * If it's not there anymore, take it out of the WindowRegion there
 
745
         * (RWFR() silently returns if we're not using WindowRegion's), and
 
746
         * add it the WindowRegion in the first WS it now occupies.
 
747
         *
 
748
         * XXX I'm not sure this is entirely sensible; it seems like just
 
749
         * unconditionally Remove/Place'ing would have the same effect?
 
750
         */
707
751
        for(ws = Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->next) {
708
752
                int mask = 1 << ws->number;
709
753
                if(oldoccupation & mask) {
718
762
                }
719
763
        }
720
764
 
 
765
        /*
 
766
         * Now set the WM_OCCUPATION property.  As up at the beginning in the
 
767
         * no-change branch, mask out the PropertyChange events while we do
 
768
         * it.
 
769
         *
 
770
         * XXX I should abstract that out into a function...
 
771
         */
721
772
        {
 
773
                char *namelist;
 
774
                int  len;
722
775
                XWindowAttributes winattrs;
 
776
                long eventMask;
723
777
 
724
778
                XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
725
779
                eventMask = winattrs.your_event_mask;
726
780
                XSelectInput(dpy, tmp_win->w, eventMask & ~PropertyChangeMask);
727
 
        }
728
781
 
729
 
        {
730
 
                char *namelist;
731
 
                int  len;
732
782
                len = GetPropertyFromMask(newoccupation, &namelist);
733
783
                XChangeProperty(dpy, tmp_win->w, XA_WM_OCCUPATION, XA_STRING, 8,
734
784
                                PropModeReplace, (unsigned char *) namelist, len);
735
785
                free(namelist);
736
 
        }
737
 
 
738
786
#ifdef EWMH
739
 
        EwmhSet_NET_WM_DESKTOP(tmp_win);
 
787
                EwmhSet_NET_WM_DESKTOP(tmp_win);
740
788
#endif
741
 
        XSelectInput(dpy, tmp_win->w, eventMask);
742
 
 
 
789
 
 
790
                XSelectInput(dpy, tmp_win->w, eventMask);
 
791
        }
 
792
 
 
793
 
 
794
        /*
 
795
         * Handle showing it up in the workspace map in the appropriate
 
796
         * places.
 
797
         *
 
798
         * Note that this whole block messes with the {new,old}occupation
 
799
         * vars.  That's "safe" because they're no longer used for their
 
800
         * original purposes, only for the WSmap changes, but it's still
 
801
         * kinda fugly.  Change to local vars at the drop of a hat with later
 
802
         * changes...
 
803
         */
743
804
        if(!WMapWindowMayBeAdded(tmp_win)) {
 
805
                /* Not showing in the map, so pretend it's nowhere */
744
806
                newoccupation = 0;
745
807
        }
746
808
        if(Scr->workSpaceMgr.noshowoccupyall) {
747
 
                /* We can safely change new/oldoccupation here, it's only used
748
 
                 * for WMapAddToList()/WMapRemoveFromList() from here on.
 
809
                /*
 
810
                 * Don't show OccupyAll.  Note that this means both OccupyAll
 
811
                 * window, AND windows manually set to occupy everything.  We
 
812
                 * don't have to adjust newoccupation, because the above
 
813
                 * conditional would have caught it, so we only need to edit old.
749
814
                 */
750
 
                /* if (newoccupation == fullOccupation)
751
 
                    newoccupation = 0; */
752
815
                if(oldoccupation == fullOccupation) {
753
816
                        oldoccupation = 0;
754
817
                }
755
818
        }
 
819
 
 
820
        /* Flip the ones that need flipping */
756
821
        changedoccupation = oldoccupation ^ newoccupation;
757
822
        for(ws = Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->next) {
758
823
                int mask = 1 << ws->number;
759
824
                if(changedoccupation & mask) {
760
825
                        if(newoccupation & mask) {
 
826
                                /* Add to WS */
761
827
                                WMapAddToList(tmp_win, ws);
762
828
                        }
763
829
                        else {
 
830
                                /*
 
831
                                 * Remove from WS.  We have to take it out of saved focus
 
832
                                 * if it were there.  Maybe there are other places we
 
833
                                 * might need to remove it from (warpring?)?
 
834
                                 */
764
835
                                WMapRemoveFromList(tmp_win, ws);
765
836
                                if(Scr->SaveWorkspaceFocus && ws->save_focus == tmp_win) {
766
837
                                        ws->save_focus = NULL;
769
840
                }
770
841
        }
771
842
 
 
843
 
 
844
        /*
 
845
         * If transients don't have their own occupation, find any transients
 
846
         * of this window and move them with it.
 
847
         */
772
848
        if(! Scr->TransientHasOccupation) {
773
849
                for(t = Scr->FirstWindow; t != NULL; t = t->next) {
774
850
                        if(t != tmp_win &&
778
854
                        }
779
855
                }
780
856
        }
 
857
 
 
858
        /* All done */
 
859
        return;
781
860
}
782
861
 
783
862
 
 
863
/*
 
864
 * Set the occupation based on the window name.  This is called if
 
865
 * AutoOccupy is set, when we get a notification about a window name
 
866
 * change.
 
867
 */
784
868
void
785
869
WmgrRedoOccupation(TwmWindow *win)
786
870
{
804
888
}
805
889
 
806
890
 
 
891
/* f.vanish */
807
892
void
808
893
WMgrRemoveFromCurrentWorkSpace(VirtualScreen *vs, TwmWindow *win)
809
894
{
828
913
}
829
914
 
830
915
 
 
916
/* f.warphere */
831
917
void
832
918
WMgrAddToCurrentWorkSpaceAndWarp(VirtualScreen *vs, char *winname)
833
919
{
834
920
        TwmWindow *tw;
835
921
        int       newoccupation;
836
922
 
 
923
        /* Find named window on this screen */
837
924
        for(tw = Scr->FirstWindow; tw != NULL; tw = tw->next) {
838
925
                if(match(winname, tw->full_name)) {
839
926
                        break;
840
927
                }
841
928
        }
 
929
 
 
930
        /* Didn't find it by name?  Try by class */
842
931
        if(!tw) {
843
932
                for(tw = Scr->FirstWindow; tw != NULL; tw = tw->next) {
844
933
                        if(match(winname, tw->class.res_name)) {
845
934
                                break;
846
935
                        }
847
936
                }
848
 
                if(!tw) {
849
 
                        for(tw = Scr->FirstWindow; tw != NULL; tw = tw->next) {
850
 
                                if(match(winname, tw->class.res_class)) {
851
 
                                        break;
852
 
                                }
 
937
        }
 
938
        if(!tw) {
 
939
                for(tw = Scr->FirstWindow; tw != NULL; tw = tw->next) {
 
940
                        if(match(winname, tw->class.res_class)) {
 
941
                                break;
853
942
                        }
854
943
                }
855
944
        }
 
945
 
 
946
        /* Still didn't find?  Beep at the user and bail. */
856
947
        if(!tw) {
857
948
                XBell(dpy, 0);
858
949
                return;
859
950
        }
 
951
 
 
952
        /* If WarpUnmapped isn't set and this isn't mapped, beep and bail */
860
953
        if((! Scr->WarpUnmapped) && (! tw->mapped)) {
861
954
                XBell(dpy, 0);
862
955
                return;
863
956
        }
 
957
 
 
958
        /* Move it here if it's not */
864
959
        if(! OCCUPY(tw, vs->wsw->currentwspc)) {
865
960
                newoccupation = tw->occupation | (1 << vs->wsw->currentwspc->number);
866
961
                ChangeOccupation(tw, newoccupation);
867
962
        }
868
963
 
 
964
        /* If we get here, WarpUnmapped is set, so map it if we need to */
869
965
        if(! tw->mapped) {
870
966
                DeIconify(tw);
871
967
        }
 
968
 
 
969
        /* And go */
872
970
        WarpToWindow(tw, Scr->RaiseOnWarp);
873
971
}
874
972