--- /dev/null
+images {
+ image: "module_icon.png" COMP;
+
+ image: "arrow_n.png" COMP;
+ image: "arrow_nw.png" COMP;
+ image: "arrow_w.png" COMP;
+ image: "arrow_sw.png" COMP;
+ image: "arrow_s.png" COMP;
+ image: "arrow_se.png" COMP;
+ image: "arrow_e.png" COMP;
+ image: "arrow_ne.png" COMP;
+}
+collections {
+ group {
+ name: "icon";
+ parts {
+ part {
+ name: "image";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.normal: "module_icon.png";
+ }
+ }
+ }
+ }
+
+ group { name: "modules/tiling/move/left/composite"; // {{{
+ min: 101 54;
+ data {
+ item: "shaped" "1";
+ }
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 101 54;
+ max: 101 54;
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_nw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 77 29;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 101 54;
+ to: "_";
+ }
+ image.normal: "arrow_nw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 42 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 63 29;
+ to: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_sw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 29;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 54;
+ to: "_";
+ }
+ image.normal: "arrow_sw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_nw";
+ target: "arrow_w";
+ target: "arrow_sw";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_nw";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_sw";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_w";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_nw";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_sw";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_w";
+ }
+ }
+ } // }}}
+ group { name: "modules/tiling/move/left"; // {{{
+ min: 101 54;
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 101 54;
+ max: 101 54;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_nw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 77 29;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 101 54;
+ to: "_";
+ }
+ image.normal: "arrow_nw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 42 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 63 29;
+ to: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_sw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 29;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 54;
+ to: "_";
+ }
+ image.normal: "arrow_sw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_nw";
+ target: "arrow_w";
+ target: "arrow_sw";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_nw";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_sw";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_w";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_nw";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_sw";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_w";
+ }
+ }
+ } // }}}
+
+ group { name: "modules/tiling/move/down/composite"; // {{{
+ min: 54 101;
+ data {
+ item: "shaped" "1";
+ }
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 54 101;
+ max: 54 101;
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_sw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 29 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 53 25;
+ to: "_";
+ }
+ image.normal: "arrow_sw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 38;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 29 59;
+ to: "_";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_se";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 29 76;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 53 101;
+ to: "_";
+ }
+ image.normal: "arrow_se.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_sw";
+ target: "arrow_s";
+ target: "arrow_se";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_sw";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_se";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_s";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_sw";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_se";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_s";
+ }
+ }
+ } // }}}
+ group { name: "modules/tiling/move/down"; // {{{
+ min: 54 101;
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 54 101;
+ max: 54 101;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_sw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 29 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 53 25;
+ to: "_";
+ }
+ image.normal: "arrow_sw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 38;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 29 59;
+ to: "_";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_se";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 29 76;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 53 101;
+ to: "_";
+ }
+ image.normal: "arrow_se.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_sw";
+ target: "arrow_s";
+ target: "arrow_se";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_sw";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_se";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_s";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_sw";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_se";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_s";
+ }
+ }
+ } // }}}
+
+ group { name: "modules/tiling/move/right/composite"; // {{{
+ min: 101 54;
+ data {
+ item: "shaped" "1";
+ }
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 101 54;
+ max: 101 54;
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_se";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 25;
+ to: "_";
+ }
+ image.normal: "arrow_se.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 38 25;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 59 54;
+ to: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_ne";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 77 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 101 24;
+ to: "_";
+ }
+ image.normal: "arrow_ne.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_se";
+ target: "arrow_e";
+ target: "arrow_ne";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_se";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_ne";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_e";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_se";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_ne";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_e";
+ }
+ }
+ } // }}}
+ group { name: "modules/tiling/move/right"; // {{{
+ min: 101 54;
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 101 54;
+ max: 101 54;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_se";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 25;
+ to: "_";
+ }
+ image.normal: "arrow_se.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 38 25;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 59 54;
+ to: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_ne";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 77 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 101 24;
+ to: "_";
+ }
+ image.normal: "arrow_ne.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_se";
+ target: "arrow_e";
+ target: "arrow_ne";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_se";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_ne";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_e";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_se";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_ne";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_e";
+ }
+ }
+ } // }}}
+
+ group { name: "modules/tiling/move/up/composite"; // {{{
+ min: 54 101;
+ data {
+ item: "shaped" "1";
+ }
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 54 101;
+ max: 54 101;
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_ne";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 76;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 101;
+ to: "_";
+ }
+ image.normal: "arrow_ne.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 25 38;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 54 59;
+ to: "_";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_nw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 25;
+ to: "_";
+ }
+ image.normal: "arrow_nw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_ne";
+ target: "arrow_n";
+ target: "arrow_nw";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_ne";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_nw";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_n";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_ne";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_nw";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_n";
+ }
+ }
+ } // }}}
+ group { name: "modules/tiling/move/up"; // {{{
+ min: 54 101;
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 54 101;
+ max: 54 101;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_ne";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 76;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 101;
+ to: "_";
+ }
+ image.normal: "arrow_ne.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 25 38;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 54 59;
+ to: "_";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_nw";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 0;
+ offset: 24 25;
+ to: "_";
+ }
+ image.normal: "arrow_nw.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_ne";
+ target: "arrow_n";
+ target: "arrow_nw";
+ after: "in1a";
+ }
+ program {
+ name: "in1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_ne";
+ after: "in2a";
+ after: "in2b";
+ }
+ program {
+ name: "in1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_nw";
+ }
+ program {
+ name: "in2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_n";
+ after: "in3a";
+ after: "in3b";
+ }
+ program {
+ name: "in2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.4;
+ target: "arrow_ne";
+ }
+ program {
+ name: "in3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.4;
+ target: "arrow_nw";
+ after: "in1a";
+ after: "in1b";
+ }
+ program {
+ name: "in3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.6;
+ target: "arrow_n";
+ }
+ }
+ } // }}}
+
+ group { name: "modules/tiling/transition/horizontal/composite"; // {{{
+ min: 29 221;
+ data {
+ item: "shaped" "1";
+ }
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 29 221;
+ max: 29 221;
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_n_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 1 0;
+ offset: 0 21;
+ to: "_";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_n_3";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_n_3";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_n_2";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_n_2";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_n_1";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_n_1";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 10;
+ to_x: "_";
+ to_y: "arrow_n_0";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 31;
+ to_x: "_";
+ to_y: "arrow_n_0";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_s_0";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_s_0";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_s_1";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_s_1";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_s_2";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_s_2";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_n_0";
+ target: "arrow_n_1";
+ target: "arrow_n_2";
+ target: "arrow_n_3";
+ target: "arrow_s_0";
+ target: "arrow_s_1";
+ target: "arrow_s_2";
+ target: "arrow_s_3";
+ after: "n0a";
+ after: "s0a";
+ }
+ program {
+ name: "n0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_0";
+ after: "n1a";
+ after: "n1b";
+ }
+ program {
+ name: "n0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_3";
+ }
+ program {
+ name: "n1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_1";
+ after: "n2a";
+ after: "n2b";
+ }
+ program {
+ name: "n1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_0";
+ }
+ program {
+ name: "n2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_2";
+ after: "n3a";
+ after: "n3b";
+ }
+ program {
+ name: "n2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_1";
+ }
+ program {
+ name: "n3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_3";
+ after: "n0a";
+ after: "n0b";
+ }
+ program {
+ name: "n3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_2";
+ }
+ program {
+ name: "s0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_0";
+ after: "s1a";
+ after: "s1b";
+ }
+ program {
+ name: "s0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_3";
+ }
+ program {
+ name: "s1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_1";
+ after: "s2a";
+ after: "s2b";
+ }
+ program {
+ name: "s1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_0";
+ }
+ program {
+ name: "s2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_2";
+ after: "s3a";
+ after: "s3b";
+ }
+ program {
+ name: "s2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_1";
+ }
+ program {
+ name: "s3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_3";
+ after: "s0a";
+ after: "s0b";
+ }
+ program {
+ name: "s3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_2";
+ }
+ }
+ } // }}}
+ group { name: "modules/tiling/transition/horizontal"; // {{{
+ min: 29 221;
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 29 221;
+ max: 29 221;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_n_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 1 0;
+ offset: 0 21;
+ to: "_";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_n_3";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_n_3";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_n_2";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_n_2";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_n_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_n_1";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_n_1";
+ }
+ image.normal: "arrow_n.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 10;
+ to_x: "_";
+ to_y: "arrow_n_0";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 31;
+ to_x: "_";
+ to_y: "arrow_n_0";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_s_0";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_s_0";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_s_1";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_s_1";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_s_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 1;
+ offset: 0 6;
+ to_x: "_";
+ to_y: "arrow_s_2";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 0 27;
+ to_x: "_";
+ to_y: "arrow_s_2";
+ }
+ image.normal: "arrow_s.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_n_0";
+ target: "arrow_n_1";
+ target: "arrow_n_2";
+ target: "arrow_n_3";
+ target: "arrow_s_0";
+ target: "arrow_s_1";
+ target: "arrow_s_2";
+ target: "arrow_s_3";
+ after: "n0a";
+ after: "s0a";
+ }
+ program {
+ name: "n0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_0";
+ after: "n1a";
+ after: "n1b";
+ }
+ program {
+ name: "n0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_3";
+ }
+ program {
+ name: "n1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_1";
+ after: "n2a";
+ after: "n2b";
+ }
+ program {
+ name: "n1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_0";
+ }
+ program {
+ name: "n2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_2";
+ after: "n3a";
+ after: "n3b";
+ }
+ program {
+ name: "n2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_1";
+ }
+ program {
+ name: "n3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_n_3";
+ after: "n0a";
+ after: "n0b";
+ }
+ program {
+ name: "n3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_n_2";
+ }
+ program {
+ name: "s0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_0";
+ after: "s1a";
+ after: "s1b";
+ }
+ program {
+ name: "s0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_3";
+ }
+ program {
+ name: "s1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_1";
+ after: "s2a";
+ after: "s2b";
+ }
+ program {
+ name: "s1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_0";
+ }
+ program {
+ name: "s2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_2";
+ after: "s3a";
+ after: "s3b";
+ }
+ program {
+ name: "s2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_1";
+ }
+ program {
+ name: "s3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_s_3";
+ after: "s0a";
+ after: "s0b";
+ }
+ program {
+ name: "s3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_s_2";
+ }
+ }
+ } // }}}
+
+ group { name: "modules/tiling/transition/vertical/composite"; // {{{
+ min: 221 29;
+ data {
+ item: "shaped" "1";
+ }
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 221 29;
+ max: 221 29;
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_w_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 1;
+ offset: 21 0;
+ to: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_w_3";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_w_3";
+ to_y: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_w_2";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_w_2";
+ to_y: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_w_1";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_w_1";
+ to_y: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 10 0;
+ to_x: "arrow_w_0";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 31 0;
+ to_x: "arrow_w_0";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_e_0";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_e_0";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_e_1";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_e_1";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_e_2";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_e_2";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_w_0";
+ target: "arrow_w_1";
+ target: "arrow_w_2";
+ target: "arrow_w_3";
+ target: "arrow_e_0";
+ target: "arrow_e_1";
+ target: "arrow_e_2";
+ target: "arrow_e_3";
+ after: "w0a";
+ after: "e0a";
+ }
+ program {
+ name: "w0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_0";
+ after: "w1a";
+ after: "w1b";
+ }
+ program {
+ name: "w0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_3";
+ }
+ program {
+ name: "w1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_1";
+ after: "w2a";
+ after: "w2b";
+ }
+ program {
+ name: "w1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_0";
+ }
+ program {
+ name: "w2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_2";
+ after: "w3a";
+ after: "w3b";
+ }
+ program {
+ name: "w2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_1";
+ }
+ program {
+ name: "w3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_3";
+ after: "w0a";
+ after: "w0b";
+ }
+ program {
+ name: "w3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_2";
+ }
+ program {
+ name: "e0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_0";
+ after: "e1a";
+ after: "e1b";
+ }
+ program {
+ name: "e0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_3";
+ }
+ program {
+ name: "e1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_1";
+ after: "e2a";
+ after: "e2b";
+ }
+ program {
+ name: "e1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_0";
+ }
+ program {
+ name: "e2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_2";
+ after: "e3a";
+ after: "e3b";
+ }
+ program {
+ name: "e2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_1";
+ }
+ program {
+ name: "e3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_3";
+ after: "e0a";
+ after: "e0b";
+ }
+ program {
+ name: "e3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_2";
+ }
+ }
+ } // }}}
+ group { name: "modules/tiling/transition/vertical"; // {{{
+ min: 221 29;
+ parts {
+ part {
+ name: "_";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ min: 221 29;
+ max: 221 29;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ rel1 {
+ relative: 0.0 0.0;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1 1;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "arrow_w_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 0 0;
+ offset: 0 0;
+ to: "_";
+ }
+ rel2 {
+ relative: 0 1;
+ offset: 21 0;
+ to: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_w_3";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_w_3";
+ to_y: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_w_2";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_w_2";
+ to_y: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_w_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_w_1";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_w_1";
+ to_y: "_";
+ }
+ image.normal: "arrow_w.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_0";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 10 0;
+ to_x: "arrow_w_0";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 31 0;
+ to_x: "arrow_w_0";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_1";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_e_0";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_e_0";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_2";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_e_1";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_e_1";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "arrow_e_3";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ rel1 {
+ relative: 1 0;
+ offset: 6 0;
+ to_x: "arrow_e_2";
+ to_y: "_";
+ }
+ rel2 {
+ relative: 1 1;
+ offset: 27 0;
+ to_x: "arrow_e_2";
+ to_y: "_";
+ }
+ image.normal: "arrow_e.png";
+ fill.smooth: 0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ color: 255 255 255 255;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "init";
+ signal: "load";
+ source: "";
+ action: STATE_SET "default" 0.0;
+ target: "arrow_w_0";
+ target: "arrow_w_1";
+ target: "arrow_w_2";
+ target: "arrow_w_3";
+ target: "arrow_e_0";
+ target: "arrow_e_1";
+ target: "arrow_e_2";
+ target: "arrow_e_3";
+ after: "w0a";
+ after: "e0a";
+ }
+ program {
+ name: "w0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_0";
+ after: "w1a";
+ after: "w1b";
+ }
+ program {
+ name: "w0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_3";
+ }
+ program {
+ name: "w1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_1";
+ after: "w2a";
+ after: "w2b";
+ }
+ program {
+ name: "w1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_0";
+ }
+ program {
+ name: "w2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_2";
+ after: "w3a";
+ after: "w3b";
+ }
+ program {
+ name: "w2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_1";
+ }
+ program {
+ name: "w3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_w_3";
+ after: "w0a";
+ after: "w0b";
+ }
+ program {
+ name: "w3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_w_2";
+ }
+ program {
+ name: "e0a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_0";
+ after: "e1a";
+ after: "e1b";
+ }
+ program {
+ name: "e0b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_3";
+ }
+ program {
+ name: "e1a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_1";
+ after: "e2a";
+ after: "e2b";
+ }
+ program {
+ name: "e1b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_0";
+ }
+ program {
+ name: "e2a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_2";
+ after: "e3a";
+ after: "e3b";
+ }
+ program {
+ name: "e2b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_1";
+ }
+ program {
+ name: "e3a";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 0.25;
+ target: "arrow_e_3";
+ after: "e0a";
+ after: "e0b";
+ }
+ program {
+ name: "e3b";
+ action: STATE_SET "default" 0.0;
+ transition: DECELERATE 0.75;
+ target: "arrow_e_2";
+ }
+ }
+ } // }}}
+}
--- /dev/null
+#include "e_mod_tiling.h"
+
+/* types {{{ */
+
+#define TILING_OVERLAY_TIMEOUT 5.0
+#define TILING_RESIZE_STEP 5
+#define TILING_POPUP_LAYER 101
+#define TILING_WRAP_SPEED 0.1
+
+typedef enum {
+ TILING_RESIZE,
+ TILING_MOVE,
+} tiling_change_t;
+
+typedef enum {
+ INPUT_MODE_NONE,
+ INPUT_MODE_SWAPPING,
+ INPUT_MODE_MOVING,
+ INPUT_MODE_GOING,
+ INPUT_MODE_TRANSITION,
+} tiling_input_mode_t;
+
+typedef enum {
+ MOVE_UP,
+ MOVE_DOWN,
+ MOVE_LEFT,
+ MOVE_RIGHT,
+
+ MOVE_COUNT
+} tiling_move_t;
+
+typedef struct geom_t {
+ int x, y, w, h;
+} geom_t;
+
+typedef struct overlay_t {
+ E_Popup *popup;
+ Evas_Object *obj;
+} overlay_t;
+
+typedef struct transition_overlay_t {
+ overlay_t overlay;
+ int stack;
+ char key[4];
+ E_Border *bd;
+} transition_overlay_t;
+
+typedef struct Border_Extra {
+ E_Border *border;
+ geom_t expected;
+ struct {
+ geom_t geom;
+ unsigned int layer;
+ E_Stacking stacking;
+ E_Maximize maximized;
+ const char *bordername;
+ } orig;
+ overlay_t overlay;
+ char key[4];
+} Border_Extra;
+
+struct tiling_g tiling_g = {
+ .module = NULL,
+ .config = NULL,
+ .log_domain = -1,
+ .default_keyhints = "asdfg;lkjh",
+};
+
+static void
+_add_border(E_Border *bd);
+
+/* }}} */
+/* Globals {{{ */
+
+static struct tiling_mod_main_g
+{
+ char edj_path[PATH_MAX];
+ E_Config_DD *config_edd,
+ *vdesk_edd;
+ int currently_switching_desktop;
+ Ecore_X_Window action_input_win;
+ Ecore_Event_Handler *handler_key,
+ *handler_border_resize,
+ *handler_border_move,
+ *handler_border_add,
+ *handler_border_remove,
+ *handler_border_iconify,
+ *handler_border_uniconify,
+ *handler_border_stick,
+ *handler_border_unstick,
+ *handler_desk_show,
+ *handler_desk_before_show,
+ *handler_desk_set,
+ *handler_container_resize;
+ E_Border_Hook *pre_border_assign_hook;
+
+ Tiling_Info *tinfo;
+ Eina_Hash *info_hash;
+ Eina_Hash *border_extras;
+ Eina_Hash *overlays;
+
+ E_Action *act_togglefloat,
+ *act_addstack,
+ *act_removestack,
+ *act_tg_stack,
+ *act_swap,
+ *act_move,
+ *act_adjusttransitions,
+ *act_go;
+
+ int warp_x,
+ warp_y,
+ old_warp_x,
+ old_warp_y,
+ warp_to_x,
+ warp_to_y;
+ Ecore_Timer *warp_timer;
+
+ overlay_t move_overlays[MOVE_COUNT];
+ transition_overlay_t *transition_overlay;
+ Ecore_Timer *action_timer;
+ E_Border *focused_bd;
+ void (*action_cb)(E_Border *bd, Border_Extra *extra);
+
+ tiling_input_mode_t input_mode;
+ char keys[4];
+} _G = {
+ .input_mode = INPUT_MODE_NONE,
+};
+
+/* }}} */
+/* Utils {{{ */
+
+/* I wonder why noone has implemented the following one yet? */
+static E_Desk *
+get_current_desk(void)
+{
+ E_Manager *m = e_manager_current_get();
+ E_Container *c = e_container_current_get(m);
+ E_Zone *z = e_zone_current_get(c);
+
+ return e_desk_current_get(z);
+}
+
+static Tiling_Info *
+_initialize_tinfo(const E_Desk *desk)
+{
+ Tiling_Info *tinfo;
+
+ tinfo = E_NEW(Tiling_Info, 1);
+ tinfo->desk = desk;
+ eina_hash_direct_add(_G.info_hash, &tinfo->desk, tinfo);
+
+ tinfo->conf = get_vdesk(tiling_g.config->vdesks, desk->x, desk->y,
+ desk->zone->num);
+
+ return tinfo;
+}
+
+static void
+check_tinfo(const E_Desk *desk)
+{
+ if (!_G.tinfo || _G.tinfo->desk != desk) {
+ _G.tinfo = eina_hash_find(_G.info_hash, &desk);
+ if (!_G.tinfo) {
+ /* lazy init */
+ _G.tinfo = _initialize_tinfo(desk);
+ }
+ if (!_G.tinfo->conf) {
+ _G.tinfo->conf = get_vdesk(tiling_g.config->vdesks,
+ desk->x, desk->y,
+ desk->zone->num);
+ }
+ }
+}
+
+static int
+is_floating_window(const E_Border *bd)
+{
+ return EINA_LIST_IS_IN(_G.tinfo->floating_windows, bd);
+}
+
+static int
+is_tilable(const E_Border *bd)
+{
+ if (bd->client.icccm.min_h == bd->client.icccm.max_h
+ && bd->client.icccm.max_h > 0)
+ return false;
+
+ if (bd->client.icccm.gravity == ECORE_X_GRAVITY_STATIC)
+ return false;
+
+ if (!tiling_g.config->tile_dialogs
+ && ((bd->client.icccm.transient_for != 0)
+ || (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)))
+ return false;
+
+ return true;
+}
+
+static void
+change_window_border(E_Border *bd,
+ const char *bordername)
+{
+ eina_stringshare_replace(&bd->bordername, bordername);
+ bd->client.border.changed = true;
+ bd->changes.border = true;
+ bd->changed = true;
+}
+
+static int
+get_stack(const E_Border *bd)
+{
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ if (EINA_LIST_IS_IN(_G.tinfo->stacks[i], bd))
+ return i;
+ }
+ return -1;
+}
+
+static int
+get_stack_count(void)
+{
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ if (!_G.tinfo->stacks[i])
+ return i;
+ }
+ return TILING_MAX_STACKS;
+}
+
+static int
+get_window_count(void)
+{
+ int res = 0;
+
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ if (!_G.tinfo->stacks[i])
+ break;
+ res += eina_list_count(_G.tinfo->stacks[i]);
+ }
+ return res;
+}
+
+static int
+get_transition_count(void)
+{
+ int res = 0;
+
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ if (!_G.tinfo->stacks[i])
+ break;
+ res += eina_list_count(_G.tinfo->stacks[i]);
+ }
+ if (_G.tinfo->stacks[0])
+ res--;
+ return res;
+}
+
+static void
+_theme_edje_object_set_aux(Evas_Object *obj, const char *group)
+{
+ if (!e_theme_edje_object_set(obj, "base/theme/modules/tiling",
+ group)) {
+ edje_object_file_set(obj, _G.edj_path, group);
+ }
+}
+#define _theme_edje_object_set(_obj, _group) \
+ if (e_config->use_composite) \
+ _theme_edje_object_set_aux(_obj, _group"/composite"); \
+ else \
+ _theme_edje_object_set_aux(_obj, _group);
+
+static Eina_Bool
+_info_hash_update(const Eina_Hash *hash, const void *key,
+ void *data, void *fdata)
+{
+ Tiling_Info *tinfo = data;
+
+ if (tinfo->desk) {
+ tinfo->conf = get_vdesk(tiling_g.config->vdesks,
+ tinfo->desk->x, tinfo->desk->y,
+ tinfo->desk->zone->num);
+ } else {
+ tinfo->conf = NULL;
+ }
+
+ return true;
+}
+
+void
+e_tiling_update_conf(void)
+{
+ eina_hash_foreach(_G.info_hash, _info_hash_update, NULL);
+}
+
+static void
+_e_border_move_resize(E_Border *bd,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ DBG("%p -> %dx%d+%d+%d", bd, w, h, x, y);
+ e_border_move_resize(bd, x, y, w, h);
+}
+
+static void
+_e_border_move(E_Border *bd,
+ int x,
+ int y)
+{
+ DBG("%p -> +%d+%d", bd, x, y);
+ e_border_move(bd, x, y);
+}
+
+static void
+_e_border_resize(E_Border *bd,
+ int w,
+ int h)
+{
+ DBG("%p -> %dx%d", bd, w, h);
+ e_border_resize(bd, w, h);
+}
+
+static void
+_e_border_maximize(E_Border *bd, E_Maximize max)
+{
+ DBG("%p -> %s", bd,
+ (max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_NONE ? "NONE" :
+ (max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL ? "VERTICAL" :
+ (max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL ? "HORIZONTAL" :
+ "BOTH");
+ DBG("new_client:%s, bd->maximized=%x",
+ bd->new_client? "true": "false",
+ bd->maximized);
+ e_border_maximize(bd, max);
+}
+
+static void
+_e_border_unmaximize(E_Border *bd, E_Maximize max)
+{
+ DBG("%p -> %s", bd,
+ (max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_NONE ? "NONE" :
+ (max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL ? "VERTICAL" :
+ (max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL ? "HORIZONTAL" :
+ "BOTH");
+ e_border_unmaximize(bd, max);
+}
+
+static void
+_restore_border(E_Border *bd)
+{
+ Border_Extra *extra;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+ _e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
+ _e_border_move_resize(bd,
+ extra->orig.geom.x,
+ extra->orig.geom.y,
+ extra->orig.geom.w,
+ extra->orig.geom.h);
+ e_border_layer_set(bd, extra->orig.layer);
+ e_hints_window_stacking_set(bd, extra->orig.stacking);
+ if (extra->orig.maximized) {
+ e_border_maximize(bd, extra->orig.maximized);
+ bd->maximized = extra->orig.maximized;
+ }
+
+
+ change_window_border(bd, extra->orig.bordername);
+}
+
+static Border_Extra *
+_get_or_create_border_extra(E_Border *bd)
+{
+ Border_Extra *extra;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ extra = E_NEW(Border_Extra, 1);
+ *extra = (Border_Extra) {
+ .border = bd,
+ .expected = {
+ .x = bd->x,
+ .y = bd->y,
+ .w = bd->w,
+ .h = bd->h,
+ },
+ .orig = {
+ .geom = {
+ .x = bd->x,
+ .y = bd->y,
+ .w = bd->w,
+ .h = bd->h,
+ },
+ .layer = bd->layer,
+ .stacking = bd->client.netwm.state.stacking,
+ .maximized = bd->maximized,
+ .bordername = eina_stringshare_add(bd->bordername),
+ },
+ };
+ eina_hash_direct_add(_G.border_extras, &extra->border, extra);
+ } else {
+ extra->expected = (geom_t) {
+ .x = bd->x,
+ .y = bd->y,
+ .w = bd->w,
+ .h = bd->h,
+ };
+ }
+
+ return extra;
+}
+
+/* }}} */
+/* Overlays {{{*/
+
+static void
+_overlays_free_cb(void *data)
+{
+ Border_Extra *extra = data;
+
+ if (extra->overlay.obj) {
+ evas_object_del(extra->overlay.obj);
+ extra->overlay.obj = NULL;
+ }
+ if (extra->overlay.popup) {
+ e_object_del(E_OBJECT(extra->overlay.popup));
+ extra->overlay.popup = NULL;
+ }
+
+ extra->key[0] = '\0';
+}
+
+static void
+end_special_input(void)
+{
+ if (_G.input_mode == INPUT_MODE_NONE)
+ return;
+
+ if (_G.overlays) {
+ eina_hash_free(_G.overlays);
+ _G.overlays = NULL;
+ }
+
+ if (_G.handler_key) {
+ ecore_event_handler_del(_G.handler_key);
+ _G.handler_key = NULL;
+ }
+ if (_G.action_input_win) {
+ e_grabinput_release(_G.action_input_win, _G.action_input_win);
+ ecore_x_window_free(_G.action_input_win);
+ _G.action_input_win = 0;
+ }
+ if (_G.action_timer) {
+ ecore_timer_del(_G.action_timer);
+ _G.action_timer = NULL;
+ }
+
+ _G.focused_bd = NULL;
+ _G.action_cb = NULL;
+
+ switch(_G.input_mode) {
+ case INPUT_MODE_MOVING:
+ for (int i = 0; i < MOVE_COUNT; i++) {
+ overlay_t *overlay = &_G.move_overlays[i];
+
+ if (overlay->obj) {
+ evas_object_del(overlay->obj);
+ overlay->obj = NULL;
+ }
+ if (overlay->popup) {
+ e_object_del(E_OBJECT(overlay->popup));
+ overlay->popup = NULL;
+ }
+ }
+ break;
+ case INPUT_MODE_TRANSITION:
+ if (_G.transition_overlay) {
+ if (_G.transition_overlay->overlay.obj) {
+ evas_object_del(_G.transition_overlay->overlay.obj);
+ }
+ if (_G.transition_overlay->overlay.popup) {
+ e_object_del(E_OBJECT(_G.transition_overlay->overlay.popup));
+ }
+ E_FREE(_G.transition_overlay);
+ _G.transition_overlay = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+
+ _G.input_mode = INPUT_MODE_NONE;
+}
+
+static Eina_Bool
+overlay_key_down(void *data,
+ int type,
+ void *event)
+{
+ Ecore_Event_Key *ev = event;
+ Border_Extra *extra;
+
+ if (ev->event_window != _G.action_input_win)
+ return ECORE_CALLBACK_PASS_ON;
+
+ if (strcmp(ev->key, "Return") == 0)
+ goto stop;
+ if (strcmp(ev->key, "Escape") == 0)
+ goto stop;
+ if (strcmp(ev->key, "Backspace") == 0) {
+ char *key = _G.keys;
+
+ while (*key)
+ key++;
+ *key = '\0';
+ return ECORE_CALLBACK_RENEW;
+ }
+
+ if (ev->key[0] && !ev->key[1] && strchr(tiling_g.config->keyhints,
+ ev->key[1])) {
+ char *key = _G.keys;
+
+ while (*key)
+ key++;
+ *key++ = ev->key[0];
+ *key = '\0';
+
+ extra = eina_hash_find(_G.overlays, _G.keys);
+ if (extra) {
+ _G.action_cb(_G.focused_bd, extra);
+ } else {
+ return ECORE_CALLBACK_RENEW;
+ }
+ }
+
+stop:
+ end_special_input();
+ return ECORE_CALLBACK_DONE;
+}
+
+static Eina_Bool
+_timeout_cb(void *data)
+{
+ end_special_input();
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_do_overlay(E_Border *focused_bd,
+ void (*action_cb)(E_Border *, Border_Extra *),
+ tiling_input_mode_t input_mode)
+{
+ Ecore_X_Window parent;
+ int nb_win;
+ int hints_len;
+ int key_len;
+ int n = 0;
+ int nmax;
+
+ end_special_input();
+
+ nb_win = get_window_count();
+ if (nb_win < 2) {
+ return;
+ }
+
+ _G.input_mode = input_mode;
+
+ _G.focused_bd = focused_bd;
+ _G.action_cb = action_cb;
+
+ _G.overlays = eina_hash_string_small_new(_overlays_free_cb);
+
+ hints_len = strlen(tiling_g.config->keyhints);
+ key_len = 1;
+ nmax = hints_len;
+ if (hints_len < nb_win) {
+ key_len = 2;
+ nmax *= hints_len;
+ if (hints_len * hints_len < nb_win) {
+ key_len = 3;
+ nmax *= hints_len;
+ }
+ }
+
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ Eina_List *l;
+ E_Border *bd;
+
+ if (!_G.tinfo->stacks[i])
+ break;
+ EINA_LIST_FOREACH(_G.tinfo->stacks[i], l, bd) {
+ if (bd != focused_bd && n < nmax) {
+ Border_Extra *extra;
+ Evas_Coord ew, eh;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ continue;
+ }
+
+ extra->overlay.popup = e_popup_new(bd->zone, 0, 0, 1, 1);
+ if (!extra->overlay.popup)
+ continue;
+
+ e_popup_layer_set(extra->overlay.popup, TILING_POPUP_LAYER);
+ extra->overlay.obj =
+ edje_object_add(extra->overlay.popup->evas);
+ e_theme_edje_object_set(extra->overlay.obj,
+ "base/theme/borders",
+ "e/widgets/border/default/resize");
+
+ switch (key_len) {
+ case 1:
+ extra->key[0] = tiling_g.config->keyhints[n];
+ extra->key[1] = '\0';
+ break;
+ case 2:
+ extra->key[0] = tiling_g.config->keyhints[n / hints_len];
+ extra->key[1] = tiling_g.config->keyhints[n % hints_len];
+ extra->key[2] = '\0';
+ break;
+ case 3:
+ extra->key[0] = tiling_g.config->keyhints[n / hints_len / hints_len];
+ extra->key[0] = tiling_g.config->keyhints[n / hints_len];
+ extra->key[1] = tiling_g.config->keyhints[n % hints_len];
+ extra->key[2] = '\0';
+ break;
+ }
+ n++;
+
+ eina_hash_add(_G.overlays, extra->key, extra);
+ edje_object_part_text_set(extra->overlay.obj,
+ "e.text.label",
+ extra->key);
+ edje_object_size_min_calc(extra->overlay.obj, &ew, &eh);
+ evas_object_move(extra->overlay.obj, 0, 0);
+ evas_object_resize(extra->overlay.obj, ew, eh);
+ evas_object_show(extra->overlay.obj);
+ e_popup_edje_bg_object_set(extra->overlay.popup,
+ extra->overlay.obj);
+
+ evas_object_show(extra->overlay.obj);
+ e_popup_show(extra->overlay.popup);
+
+ e_popup_move_resize(extra->overlay.popup,
+ (bd->x - extra->overlay.popup->zone->x) +
+ ((bd->w - ew) / 2),
+ (bd->y - extra->overlay.popup->zone->y) +
+ ((bd->h - eh) / 2),
+ ew, eh);
+
+ e_popup_show(extra->overlay.popup);
+ }
+ }
+ }
+
+ /* Get input */
+ parent = _G.tinfo->desk->zone->container->win;
+ _G.action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
+ if (!_G.action_input_win) {
+ end_special_input();
+ return;
+ }
+
+ ecore_x_window_show(_G.action_input_win);
+ if (!e_grabinput_get(_G.action_input_win, 0, _G.action_input_win)) {
+ end_special_input();
+ return;
+ }
+ _G.action_timer = ecore_timer_add(TILING_OVERLAY_TIMEOUT,
+ _timeout_cb, NULL);
+
+ _G.keys[0] = '\0';
+ _G.handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
+ overlay_key_down, NULL);
+}
+
+/* }}} */
+/* Reorganize Stacks {{{*/
+
+static void
+_reorganize_stack(int stack)
+{
+ if (stack < 0 || stack >= TILING_MAX_STACKS
+ || !_G.tinfo->stacks[stack])
+ return;
+
+ if (_G.tinfo->stacks[stack]->next) {
+ int zx, zy, zw, zh, i = 0, count;
+
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone, &zx, &zy, &zw, &zh);
+
+ count = eina_list_count(_G.tinfo->stacks[stack]);
+
+ if (_G.tinfo->conf->use_rows) {
+ int y, w, h, cw;
+
+ y = _G.tinfo->pos[stack];
+ cw = 0;
+ w = zw / count;
+ h = _G.tinfo->size[stack];
+
+ for (Eina_List *l = _G.tinfo->stacks[stack]; l; l = l->next, i++) {
+ E_Border *bd = l->data;
+ Border_Extra *extra;
+ int d = (i * 2 * zw) % count
+ - (2 * cw) % count;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ continue;
+ }
+
+ if ((bd->maximized & E_MAXIMIZE_HORIZONTAL) && count != 1) {
+ _e_border_unmaximize(bd, E_MAXIMIZE_HORIZONTAL);
+ }
+ /* let's use a bresenham here */
+
+ extra->expected.x = cw + zx;
+ extra->expected.y = y;
+ extra->expected.w = w + d;
+ extra->expected.h = h;
+ cw += extra->expected.w;
+
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ }
+ } else {
+ int x, w, h, ch;
+
+ x = _G.tinfo->pos[stack];
+ ch = 0;
+ w = _G.tinfo->size[stack];
+ h = zh / count;
+
+ for (Eina_List *l = _G.tinfo->stacks[stack]; l; l = l->next, i++) {
+ E_Border *bd = l->data;
+ Border_Extra *extra;
+ int d = (i * 2 * zh) % count
+ - (2 * ch) % count;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ continue;
+ }
+
+ if ((bd->maximized & E_MAXIMIZE_VERTICAL) && count != 1) {
+ _e_border_unmaximize(bd, E_MAXIMIZE_VERTICAL);
+ }
+ /* let's use a bresenham here */
+
+ extra->expected.x = x;
+ extra->expected.y = ch + zy;
+ extra->expected.w = w;
+ extra->expected.h = h + d;
+ ch += extra->expected.h;
+
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ }
+ }
+ } else {
+ Border_Extra *extra;
+ E_Border *bd = _G.tinfo->stacks[stack]->data;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+
+ if (_G.tinfo->conf->use_rows) {
+ int x, w;
+
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ &x, NULL, &w, NULL);
+
+ extra->expected.x = x;
+ extra->expected.y = _G.tinfo->pos[stack];
+ extra->expected.w = w;
+ extra->expected.h = _G.tinfo->size[stack];
+
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND | E_MAXIMIZE_HORIZONTAL);
+ } else {
+ int y, h;
+
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ NULL, &y, NULL, &h);
+
+ extra->expected.x = _G.tinfo->pos[stack];
+ extra->expected.y = y;
+ extra->expected.w = _G.tinfo->size[stack];
+ extra->expected.h = h;
+
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND | E_MAXIMIZE_VERTICAL);
+ }
+ }
+}
+
+static void
+_move_resize_stack(int stack, int delta_pos, int delta_size)
+{
+ Eina_List *list = _G.tinfo->stacks[stack];
+
+ for (Eina_List *l = list; l; l = l->next) {
+ E_Border *bd = l->data;
+ Border_Extra *extra;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ continue;
+ }
+
+ if (_G.tinfo->conf->use_rows) {
+ extra->expected.y += delta_pos;
+ extra->expected.h += delta_size;
+ } else {
+ extra->expected.x += delta_pos;
+ extra->expected.w += delta_size;
+ }
+
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ }
+
+ _G.tinfo->pos[stack] += delta_pos;
+ _G.tinfo->size[stack] += delta_size;
+}
+
+static void
+_set_stack_geometry(int stack, int pos, int size)
+{
+ for (Eina_List *l = _G.tinfo->stacks[stack]; l; l = l->next) {
+ E_Border *bd = l->data;
+ Border_Extra *extra;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ continue;
+ }
+ DBG("expected: %dx%d+%d+%d (%p)",
+ extra->expected.w,
+ extra->expected.h,
+ extra->expected.x,
+ extra->expected.y,
+ bd);
+
+ if (_G.tinfo->conf->use_rows) {
+ extra->expected.y = pos;
+ extra->expected.h = size;
+
+ if (bd->maximized) {
+ if (l->next && (bd->maximized & E_MAXIMIZE_HORIZONTAL))
+ _e_border_unmaximize(bd, E_MAXIMIZE_HORIZONTAL);
+ if (_G.tinfo->stacks[1] && (bd->maximized & E_MAXIMIZE_VERTICAL))
+ _e_border_unmaximize(bd, E_MAXIMIZE_VERTICAL);
+ }
+ } else {
+ extra->expected.x = pos;
+ extra->expected.w = size;
+
+ if (bd->maximized) {
+ if (l->next && (bd->maximized & E_MAXIMIZE_VERTICAL))
+ _e_border_unmaximize(bd, E_MAXIMIZE_VERTICAL);
+ if (_G.tinfo->stacks[1] && (bd->maximized & E_MAXIMIZE_HORIZONTAL))
+ _e_border_unmaximize(bd, E_MAXIMIZE_HORIZONTAL);
+ }
+ }
+
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ }
+ _G.tinfo->pos[stack] = pos;
+ _G.tinfo->size[stack] = size;
+}
+
+static void
+_add_stack(void)
+{
+ int nb_borders;
+
+ if (_G.tinfo->conf->nb_stacks == TILING_MAX_STACKS)
+ return;
+
+ _G.tinfo->conf->nb_stacks++;
+
+ if (_G.tinfo->conf->nb_stacks == 1) {
+ for (Eina_List *l = e_border_focus_stack_get(); l; l = l->next) {
+ E_Border *bd;
+
+ bd = l->data;
+ if (bd->desk == _G.tinfo->desk)
+ _add_border(bd);
+ }
+ }
+ nb_borders = get_window_count();
+ if (_G.tinfo->stacks[_G.tinfo->conf->nb_stacks - 2]
+ && nb_borders >= _G.tinfo->conf->nb_stacks)
+ {
+ int nb_stacks = _G.tinfo->conf->nb_stacks - 1;
+ int pos, s;
+ /* Add stack */
+
+ if (_G.tinfo->conf->use_rows)
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ NULL, &pos, NULL, &s);
+ else
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ &pos, NULL, &s, NULL);
+
+ for (int i = 0; i <= nb_stacks; i++) {
+ int size = 0;
+
+ size = s / (nb_stacks + 1 - i);
+
+ _set_stack_geometry(i, pos, size);
+
+ s -= size;
+ pos += size;
+ }
+ for (int i = nb_stacks - 1; i >= 0; i--) {
+ if (eina_list_count(_G.tinfo->stacks[i]) == 1) {
+ _G.tinfo->stacks[i+1] = _G.tinfo->stacks[i];
+ _reorganize_stack(i+1);
+ } else {
+ E_Border *bd = eina_list_last(_G.tinfo->stacks[i])->data;
+
+ EINA_LIST_REMOVE(_G.tinfo->stacks[i], bd);
+ _reorganize_stack(i);
+
+ _G.tinfo->stacks[i+1] = NULL;
+ EINA_LIST_APPEND(_G.tinfo->stacks[i+1], bd);
+ _reorganize_stack(i+1);
+ return;
+ }
+ }
+ }
+}
+
+static void
+_remove_stack(void)
+{
+ if (!_G.tinfo->conf->nb_stacks)
+ return;
+
+ _G.tinfo->conf->nb_stacks--;
+
+ if (!_G.tinfo->conf->nb_stacks) {
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ for (Eina_List *l = _G.tinfo->stacks[i]; l; l = l->next) {
+ E_Border *bd = l->data;
+
+ _restore_border(bd);
+ }
+ eina_list_free(_G.tinfo->stacks[i]);
+ _G.tinfo->stacks[i] = NULL;
+ }
+ e_place_zone_region_smart_cleanup(_G.tinfo->desk->zone);
+ } else {
+ int nb_stacks = _G.tinfo->conf->nb_stacks;
+ int stack = _G.tinfo->conf->nb_stacks;
+ int pos, s;
+
+ if (_G.tinfo->stacks[stack]) {
+ _G.tinfo->stacks[stack-1] = eina_list_merge(
+ _G.tinfo->stacks[stack-1], _G.tinfo->stacks[stack]);
+ _reorganize_stack(stack-1);
+ }
+
+ if (_G.tinfo->conf->use_rows) {
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ NULL, &pos, NULL, &s);
+ } else {
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ &pos, NULL, &s, NULL);
+ }
+ for (int i = 0; i < nb_stacks; i++) {
+ int size = 0;
+
+ size = s / (nb_stacks - i);
+
+ _set_stack_geometry(i, pos, size);
+
+ s -= size;
+ pos += size;
+ }
+ }
+}
+
+static void
+_toggle_rows_cols(void)
+{
+#if 0
+ Eina_List *wins = NULL;
+ E_Border *bd;
+
+ _G.tinfo->conf->use_rows = !_G.tinfo->conf->use_rows;
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ EINA_LIST_FREE(_G.tinfo->stacks[i], bd) {
+ EINA_LIST_APPEND(wins, bd);
+ _restore_border(bd);
+ }
+ _G.tinfo->stacks[i] = NULL;
+ _G.tinfo->pos[i] = 0;
+ _G.tinfo->size[i] = 0;
+ }
+
+ DBG("reinsert (use_rows: %s)",
+ _G.tinfo->conf->use_rows ? "true":"false");
+
+ EINA_LIST_FREE(wins, bd) {
+ _add_border(bd);
+ }
+#else
+ int nb_stacks = _G.tinfo->conf->nb_stacks;
+ int pos, s;
+
+ _G.tinfo->conf->use_rows = !_G.tinfo->conf->use_rows;
+
+ if (_G.tinfo->conf->use_rows)
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ NULL, &pos, NULL, &s);
+ else
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone,
+ &pos, NULL, &s, NULL);
+
+ for (int i = 0; i < nb_stacks; i++) {
+ int size = 0;
+
+ size = s / (nb_stacks - i);
+
+ _set_stack_geometry(i, pos, size);
+
+ s -= size;
+ pos += size;
+ }
+ for (int i = 0; i < nb_stacks; i++) {
+ _reorganize_stack(i);
+ }
+#endif
+}
+
+void
+change_desk_conf(struct _Config_vdesk *newconf)
+{
+ E_Manager *m;
+ E_Container *c;
+ E_Zone *z;
+ E_Desk *d;
+ int old_nb_stacks = 0,
+ new_nb_stacks = newconf->nb_stacks;
+
+ m = e_manager_current_get();
+ if (!m) return;
+ c = e_container_current_get(m);
+ if (!c) return;
+ z = e_container_zone_number_get(c, newconf->zone_num);
+ if (!z) return;
+ d = e_desk_at_xy_get(z, newconf->x, newconf->y);
+ if (!d) return;
+
+ check_tinfo(d);
+ if (_G.tinfo->conf) {
+ old_nb_stacks = _G.tinfo->conf->nb_stacks;
+ if (_G.tinfo->conf->use_rows != newconf->use_rows) {
+ _G.tinfo->conf = newconf;
+ _G.tinfo->conf->use_rows = !_G.tinfo->conf->use_rows;
+ _toggle_rows_cols();
+ return;
+ }
+ } else {
+ newconf->nb_stacks = 0;
+ }
+ _G.tinfo->conf = newconf;
+ _G.tinfo->conf->nb_stacks = old_nb_stacks;
+
+ if (new_nb_stacks == old_nb_stacks)
+ return;
+
+ if (new_nb_stacks == 0) {
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ for (Eina_List *l = _G.tinfo->stacks[i]; l; l = l->next) {
+ E_Border *bd = l->data;
+
+ _restore_border(bd);
+ }
+ eina_list_free(_G.tinfo->stacks[i]);
+ _G.tinfo->stacks[i] = NULL;
+ }
+ e_place_zone_region_smart_cleanup(z);
+ } else if (new_nb_stacks > old_nb_stacks) {
+ for (int i = new_nb_stacks; i > old_nb_stacks; i--) {
+ _add_stack();
+ }
+ } else {
+ for (int i = new_nb_stacks; i < old_nb_stacks; i++) {
+ _remove_stack();
+ }
+ }
+ _G.tinfo->conf->nb_stacks = new_nb_stacks;
+}
+
+static void
+_e_mod_action_add_stack_cb(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk = get_current_desk();
+
+ end_special_input();
+
+ check_tinfo(desk);
+
+ _add_stack();
+
+ e_config_save_queue();
+}
+
+static void
+_e_mod_action_remove_stack_cb(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk = get_current_desk();
+
+ end_special_input();
+
+ check_tinfo(desk);
+
+ _remove_stack();
+
+ e_config_save_queue();
+}
+
+static void
+_e_mod_action_tg_stack_cb(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk = get_current_desk();
+
+ end_special_input();
+
+ check_tinfo(desk);
+
+ _toggle_rows_cols();
+
+ e_config_save_queue();
+}
+
+
+/* }}} */
+/* Reorganize windows {{{*/
+
+static void
+_add_border(E_Border *bd)
+{
+ Border_Extra *extra;
+ int stack;
+
+ if (!bd) {
+ return;
+ }
+ if (is_floating_window(bd)) {
+ return;
+ }
+ if (!is_tilable(bd)) {
+ return;
+ }
+ if (bd->fullscreen) {
+ return;
+ }
+
+ if (!_G.tinfo || !_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ extra = _get_or_create_border_extra(bd);
+
+ /* Stack tiled window below so that winlist doesn't mix up stacking */
+ e_border_layer_set(bd, 75);
+ e_hints_window_stacking_set(bd, E_STACKING_BELOW);
+
+ DBG("adding %p", bd);
+
+ if (_G.tinfo->stacks[0]) {
+ DBG("got stack 0");
+ if (_G.tinfo->stacks[_G.tinfo->conf->nb_stacks - 1]) {
+ DBG("using last stack");
+ stack = _G.tinfo->conf->nb_stacks - 1;
+
+ if (!_G.tinfo->stacks[stack]->next) {
+ _e_border_unmaximize(_G.tinfo->stacks[stack]->data,
+ E_MAXIMIZE_BOTH);
+ }
+ EINA_LIST_APPEND(_G.tinfo->stacks[stack], bd);
+ _reorganize_stack(stack);
+ if (bd->maximized)
+ _e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
+ } else {
+ /* Add stack */
+ int nb_stacks = get_stack_count();
+ int x, y, w, h;
+ int pos, s, size = 0;
+
+ DBG("add stack");
+
+ e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
+
+ if (_G.tinfo->conf->use_rows) {
+ pos = y;
+ s = h;
+ } else {
+ pos = x;
+ s = w;
+ }
+
+ EINA_LIST_APPEND(_G.tinfo->stacks[nb_stacks], bd);
+
+ for (int i = 0; i < nb_stacks; i++) {
+
+ size = s / (nb_stacks + 1 - i);
+
+ _set_stack_geometry(i, pos, size);
+
+ s -= size;
+ pos += size;
+ }
+
+ _G.tinfo->pos[nb_stacks] = pos;
+ _G.tinfo->size[nb_stacks] = size;
+ if (_G.tinfo->conf->use_rows) {
+ extra->expected.x = x;
+ extra->expected.y = pos;
+ extra->expected.w = w;
+ extra->expected.h = size;
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND |
+ E_MAXIMIZE_HORIZONTAL);
+ } else {
+ extra->expected.x = pos;
+ extra->expected.y = y;
+ extra->expected.w = size;
+ extra->expected.h = h;
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND |
+ E_MAXIMIZE_VERTICAL);
+ }
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+
+ stack = nb_stacks;
+ }
+ } else {
+ DBG("lonely window");
+ e_zone_useful_geometry_get(bd->zone,
+ &extra->expected.x,
+ &extra->expected.y,
+ &extra->expected.w,
+ &extra->expected.h);
+
+ if (bd->maximized & E_MAXIMIZE_BOTH)
+ _e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND | E_MAXIMIZE_BOTH);
+ EINA_LIST_APPEND(_G.tinfo->stacks[0], bd);
+ if (_G.tinfo->conf->use_rows) {
+ e_zone_useful_geometry_get(bd->zone,
+ NULL, &_G.tinfo->pos[0],
+ NULL, &_G.tinfo->size[0]);
+ } else {
+ e_zone_useful_geometry_get(bd->zone,
+ &_G.tinfo->pos[0], NULL,
+ &_G.tinfo->size[0], NULL);
+ }
+ stack = 0;
+ }
+ DBG("expected: %dx%d+%d+%d (%p)",
+ extra->expected.w,
+ extra->expected.h,
+ extra->expected.x,
+ extra->expected.y,
+ bd);
+}
+
+static void
+_remove_border(E_Border *bd)
+{
+ int stack;
+ int nb_stacks;
+
+ nb_stacks = get_stack_count();
+
+ stack = get_stack(bd);
+ if (stack < 0)
+ return;
+
+ DBG("removing %p (%d%c)", bd, stack, _G.tinfo->conf->use_rows? 'r':'c');
+
+ EINA_LIST_REMOVE(_G.tinfo->stacks[stack], bd);
+ eina_hash_del(_G.border_extras, bd, NULL);
+
+ if (_G.tinfo->stacks[stack]) {
+ _reorganize_stack(stack);
+ } else {
+ int nb_borders = get_window_count();
+
+ if (nb_stacks > nb_borders) {
+ int pos, s;
+ /* Remove stack */
+
+ nb_stacks--;
+
+ for (int i = stack; i < nb_stacks; i++) {
+ _G.tinfo->stacks[i] = _G.tinfo->stacks[i+1];
+ }
+ _G.tinfo->stacks[nb_stacks] = NULL;
+ if (_G.tinfo->conf->use_rows) {
+ e_zone_useful_geometry_get(bd->zone,
+ NULL, &pos, NULL, &s);
+ } else {
+ e_zone_useful_geometry_get(bd->zone,
+ &pos, NULL, &s, NULL);
+ }
+ for (int i = 0; i < nb_stacks; i++) {
+ int size;
+
+ size = s / (nb_stacks - i);
+
+ _set_stack_geometry(i, pos, size);
+
+ s -= size;
+ pos += size;
+ }
+ } else {
+ for (int i = stack+1; i < nb_stacks; i++) {
+ if (eina_list_count(_G.tinfo->stacks[i]) > 1) {
+ for (int j = stack; j < i - 1; j++) {
+ _G.tinfo->stacks[j] = _G.tinfo->stacks[j+1];
+ _reorganize_stack(j);
+ }
+ bd = _G.tinfo->stacks[i]->data;
+ EINA_LIST_REMOVE(_G.tinfo->stacks[i], bd);
+ _reorganize_stack(i);
+
+ _G.tinfo->stacks[i-1] = NULL;
+ EINA_LIST_APPEND(_G.tinfo->stacks[i-1], bd);
+ _reorganize_stack(i-1);
+ return;
+ }
+ }
+ for (int i = stack-1; i >= 0; i--) {
+ if (eina_list_count(_G.tinfo->stacks[i]) == 1) {
+ _G.tinfo->stacks[i+1] = _G.tinfo->stacks[i];
+ _reorganize_stack(i+1);
+ } else {
+ bd = eina_list_last(_G.tinfo->stacks[i])->data;
+ EINA_LIST_REMOVE(_G.tinfo->stacks[i], bd);
+ _reorganize_stack(i);
+
+ _G.tinfo->stacks[i+1] = NULL;
+ EINA_LIST_APPEND(_G.tinfo->stacks[i+1], bd);
+ _reorganize_stack(i+1);
+ return;
+ }
+ }
+ }
+ }
+}
+
+static void
+_move_resize_border_stack(E_Border *bd, Border_Extra *extra,
+ int stack, tiling_change_t change)
+{
+#define _MOVE_RESIZE_BORDER_STACK(_pos, _size) \
+ if (change == TILING_RESIZE) { \
+ if (stack == TILING_MAX_STACKS || !_G.tinfo->stacks[stack + 1]) { \
+ /* You're not allowed to resize */ \
+ bd->_size = extra->expected._size; \
+ } else { \
+ int delta = bd->_size - extra->expected._size; \
+ \
+ if (delta + 1 > _G.tinfo->size[stack + 1]) \
+ delta = _G.tinfo->size[stack + 1] - 1; \
+ \
+ _move_resize_stack(stack, 0, delta); \
+ _move_resize_stack(stack + 1, delta, -delta); \
+ extra->expected._size = bd->_size; \
+ } \
+ } else { \
+ if (stack == 0) { \
+ /* You're not allowed to move */ \
+ bd->_pos = extra->expected._pos; \
+ } else { \
+ int delta = bd->_pos - extra->expected._pos; \
+ \
+ if (delta + 1 > _G.tinfo->size[stack - 1]) \
+ delta = _G.tinfo->size[stack - 1] - 1; \
+ \
+ _move_resize_stack(stack, delta, -delta); \
+ _move_resize_stack(stack - 1, 0, delta); \
+ extra->expected._pos = bd->_pos; \
+ } \
+ }
+ if (_G.tinfo->conf->use_rows) {
+ _MOVE_RESIZE_BORDER_STACK(y, h)
+ } else {
+ _MOVE_RESIZE_BORDER_STACK(x, w)
+ }
+#undef _MOVE_RESIZE_BORDER_STACK
+}
+
+static void
+_move_resize_border_in_stack(E_Border *bd, Border_Extra *extra,
+ int stack, tiling_change_t change)
+{
+ Eina_List *l;
+
+ l = eina_list_data_find_list(_G.tinfo->stacks[stack], bd);
+ if (!l) {
+ ERR("unable to bd %p in stack %d", bd, stack);
+ return;
+ }
+
+ switch (change) {
+ case TILING_RESIZE:
+ if (!l->next) {
+ if (l->prev) {
+ E_Border *prevbd = l->prev->data;
+ Border_Extra *prevextra;
+
+ prevextra = eina_hash_find(_G.border_extras, &prevbd);
+ if (!prevextra) {
+ ERR("No extra for %p", prevbd);
+ return;
+ }
+
+ if (_G.tinfo->conf->use_rows) {
+ int delta;
+
+ delta = bd->w - extra->expected.w;
+ prevextra->expected.w -= delta;
+ extra->expected.x -= delta;
+ extra->expected.w = bd->w;
+ } else {
+ int delta;
+
+ delta = bd->h - extra->expected.h;
+ prevextra->expected.h -= delta;
+ extra->expected.y -= delta;
+ extra->expected.h = bd->h;
+ }
+
+ _e_border_resize(prevbd,
+ prevextra->expected.w,
+ prevextra->expected.h);
+ _e_border_move(bd,
+ extra->expected.x,
+ extra->expected.y);
+ } else {
+ /* You're not allowed to resize */
+ _e_border_resize(bd,
+ extra->expected.w,
+ extra->expected.h);
+ }
+ } else {
+ E_Border *nextbd = l->next->data;
+ Border_Extra *nextextra;
+
+ nextextra = eina_hash_find(_G.border_extras, &nextbd);
+ if (!nextextra) {
+ ERR("No extra for %p", nextbd);
+ return;
+ }
+
+ if (_G.tinfo->conf->use_rows) {
+ int min_width = MAX(nextbd->client.icccm.base_w, 1);
+ int delta;
+
+ delta = bd->w - extra->expected.w;
+ if (nextextra->expected.w - delta < min_width)
+ delta = nextextra->expected.w - min_width;
+
+ nextextra->expected.x += delta;
+ nextextra->expected.w -= delta;
+
+ extra->expected.w += delta;
+ } else {
+ int min_height = MAX(nextbd->client.icccm.base_h, 1);
+ int delta;
+
+ delta = bd->h - extra->expected.h;
+ if (nextextra->expected.h - delta < min_height)
+ delta = nextextra->expected.h - min_height;
+
+ nextextra->expected.y += delta;
+ nextextra->expected.h -= delta;
+
+ extra->expected.h += delta;
+ }
+
+ _e_border_move_resize(nextbd,
+ nextextra->expected.x,
+ nextextra->expected.y,
+ nextextra->expected.w,
+ nextextra->expected.h);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ }
+ break;
+ case TILING_MOVE:
+ if (!l->prev) {
+ /* You're not allowed to move */
+ if (_G.tinfo->conf->use_rows) {
+ bd->x = extra->expected.x;
+ } else {
+ bd->y = extra->expected.y;
+ }
+ _e_border_move(bd,
+ extra->expected.x,
+ extra->expected.y);
+ DBG("trying to move %p, but !l->prev", bd);
+ } else {
+ E_Border *prevbd = l->prev->data;
+ Border_Extra *prevextra;
+
+ prevextra = eina_hash_find(_G.border_extras, &prevbd);
+ if (!prevextra) {
+ ERR("No extra for %p", prevbd);
+ return;
+ }
+
+ if (_G.tinfo->conf->use_rows) {
+ int delta = bd->x - extra->expected.x;
+ int min_width = MAX(prevbd->client.icccm.base_w, 1);
+
+ if (prevextra->expected.w - delta < min_width)
+ delta = prevextra->expected.w - min_width;
+
+ prevextra->expected.w += delta;
+
+ extra->expected.x += delta;
+ extra->expected.w -= delta;
+ } else {
+ int delta = bd->y - extra->expected.y;
+ int min_height = MAX(prevbd->client.icccm.base_h, 1);
+
+ if (prevextra->expected.h - delta < min_height)
+ delta = prevextra->expected.h - min_height;
+
+ prevextra->expected.h += delta;
+
+ extra->expected.y += delta;
+ extra->expected.h -= delta;
+ }
+
+ _e_border_resize(prevbd,
+ prevextra->expected.w,
+ prevextra->expected.h);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ }
+ break;
+ default:
+ ERR("invalid tiling change: %d", change);
+ }
+}
+
+/* }}} */
+/* Toggle Floating {{{ */
+
+static void
+toggle_floating(E_Border *bd)
+{
+ if (!bd)
+ return;
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks)
+ return;
+
+ if (EINA_LIST_IS_IN(_G.tinfo->floating_windows, bd)) {
+ EINA_LIST_REMOVE(_G.tinfo->floating_windows, bd);
+
+ _add_border(bd);
+ } else {
+ _remove_border(bd);
+ _restore_border(bd);
+ }
+}
+
+static void
+_e_mod_action_toggle_floating_cb(E_Object *obj,
+ const char *params)
+{
+ end_special_input();
+
+ toggle_floating(e_border_focused_get());
+}
+
+/* }}} */
+/* {{{ Swap */
+
+static void
+_action_swap(E_Border *bd_1,
+ Border_Extra *extra_2)
+{
+ Border_Extra *extra_1;
+ E_Border *bd_2 = extra_2->border;
+ Eina_List *l_1 = NULL,
+ *l_2 = NULL;
+ geom_t gt;
+ unsigned int bd_2_maximized;
+
+ extra_1 = eina_hash_find(_G.border_extras, &bd_1);
+ if (!extra_1) {
+ ERR("No extra for %p", bd_1);
+ return;
+ }
+
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ if ((l_1 = eina_list_data_find_list(_G.tinfo->stacks[i], bd_1))) {
+ break;
+ }
+ }
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ if ((l_2 = eina_list_data_find_list(_G.tinfo->stacks[i], bd_2))) {
+ break;
+ }
+ }
+
+ if (!l_1 || !l_2) {
+ return;
+ }
+
+ l_1->data = bd_2;
+ l_2->data = bd_1;
+
+ gt = extra_2->expected;
+ extra_2->expected = extra_1->expected;
+ extra_1->expected = gt;
+
+ bd_2_maximized = bd_2->maximized;
+ if (bd_2->maximized)
+ _e_border_unmaximize(bd_2, E_MAXIMIZE_BOTH);
+ if (bd_1->maximized) {
+ _e_border_unmaximize(bd_1, E_MAXIMIZE_BOTH);
+ _e_border_maximize(bd_2, bd_1->maximized);
+ }
+ if (bd_2_maximized) {
+ _e_border_maximize(bd_1, bd_2_maximized);
+ }
+ _e_border_move_resize(bd_1,
+ extra_1->expected.x,
+ extra_1->expected.y,
+ extra_1->expected.w,
+ extra_1->expected.h);
+ _e_border_move_resize(bd_2,
+ extra_2->expected.x,
+ extra_2->expected.y,
+ extra_2->expected.w,
+ extra_2->expected.h);
+}
+
+static void
+_e_mod_action_swap_cb(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk;
+ E_Border *focused_bd;
+
+ desk = get_current_desk();
+ if (!desk)
+ return;
+
+ focused_bd = e_border_focused_get();
+ if (!focused_bd || focused_bd->desk != desk)
+ return;
+
+ check_tinfo(desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ _do_overlay(focused_bd, _action_swap, INPUT_MODE_SWAPPING);
+}
+
+/* }}} */
+/* Move {{{*/
+
+static void
+_check_moving_anims(const E_Border *bd, const Border_Extra *extra, int stack)
+{
+ Eina_List *l = NULL;
+ overlay_t *overlay;
+ int nb_stacks = get_stack_count();
+
+ if (stack < 0) {
+ stack = get_stack(bd);
+ if (stack < 0)
+ return;
+ }
+ if (!extra) {
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+ }
+ l = eina_list_data_find_list(_G.tinfo->stacks[stack], bd);
+ if (!l)
+ return;
+
+ /* move left */
+ overlay = &_G.move_overlays[MOVE_LEFT];
+ if ((!_G.tinfo->conf->use_rows && stack > 0)
+ || (_G.tinfo->conf->use_rows && l->prev)) {
+ if (overlay->popup) {
+ Evas_Coord ew, eh;
+
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_move(_G.move_overlays[MOVE_LEFT].popup,
+ extra->expected.x - ew/2,
+ extra->expected.y + extra->expected.h/2 - eh/2);
+ } else {
+ Evas_Coord ew, eh;
+
+ overlay->popup = e_popup_new(bd->zone, 0, 0, 1, 1);
+ if (!overlay->popup)
+ return;
+
+ e_popup_layer_set(overlay->popup, TILING_POPUP_LAYER);
+ overlay->obj = edje_object_add(overlay->popup->evas);
+ _theme_edje_object_set(overlay->obj,
+ "modules/tiling/move/left");
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_edje_bg_object_set(overlay->popup,
+ overlay->obj);
+ evas_object_show(overlay->obj);
+ e_popup_move_resize(overlay->popup,
+ extra->expected.x - ew/2
+ - overlay->popup->zone->x,
+ extra->expected.y + extra->expected.h/2
+ - eh/2
+ - overlay->popup->zone->y,
+ ew,
+ eh);
+ evas_object_resize(overlay->obj, ew, eh);
+
+ e_popup_show(overlay->popup);
+ }
+ } else if (overlay->popup) {
+ if (overlay->obj) {
+ evas_object_del(overlay->obj);
+ overlay->obj = NULL;
+ }
+ if (overlay->popup) {
+ e_object_del(E_OBJECT(overlay->popup));
+ overlay->popup = NULL;
+ }
+ }
+
+ /* move right */
+ overlay = &_G.move_overlays[MOVE_RIGHT];
+ if ((_G.tinfo->conf->use_rows && l->next)
+ || (!_G.tinfo->conf->use_rows && (
+ stack != TILING_MAX_STACKS - 1
+ && ((stack == nb_stacks - 1 && _G.tinfo->stacks[stack]->next)
+ || (stack != nb_stacks - 1))))) {
+ if (overlay->popup) {
+ Evas_Coord ew, eh;
+
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_move(_G.move_overlays[MOVE_RIGHT].popup,
+ extra->expected.x + extra->expected.w - ew/2,
+ extra->expected.y + extra->expected.h/2 - eh/2);
+ } else {
+ Evas_Coord ew, eh;
+
+ overlay->popup = e_popup_new(bd->zone, 0, 0, 1, 1);
+ if (!overlay->popup)
+ return;
+
+ e_popup_layer_set(overlay->popup, TILING_POPUP_LAYER);
+ overlay->obj = edje_object_add(overlay->popup->evas);
+ _theme_edje_object_set(overlay->obj,
+ "modules/tiling/move/right");
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_edje_bg_object_set(overlay->popup,
+ overlay->obj);
+ evas_object_show(overlay->obj);
+ e_popup_move_resize(overlay->popup,
+ extra->expected.x + extra->expected.w - ew/2
+ - overlay->popup->zone->x,
+ extra->expected.y + extra->expected.h/2
+ - eh/2
+ - overlay->popup->zone->y,
+ ew,
+ eh);
+ evas_object_resize(overlay->obj, ew, eh);
+
+ e_popup_show(overlay->popup);
+ }
+ } else if (overlay->popup) {
+ if (overlay->obj) {
+ evas_object_del(overlay->obj);
+ overlay->obj = NULL;
+ }
+ if (overlay->popup) {
+ e_object_del(E_OBJECT(overlay->popup));
+ overlay->popup = NULL;
+ }
+ }
+
+ /* move up */
+ overlay = &_G.move_overlays[MOVE_UP];
+ if ((!_G.tinfo->conf->use_rows && l->prev)
+ || (_G.tinfo->conf->use_rows && stack > 0)) {
+ if (overlay->popup) {
+ Evas_Coord ew, eh;
+
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_move(_G.move_overlays[MOVE_UP].popup,
+ extra->expected.x + extra->expected.w/2 - ew/2,
+ extra->expected.y - eh/2);
+ } else {
+ Evas_Coord ew, eh;
+
+ overlay->popup = e_popup_new(bd->zone, 0, 0, 1, 1);
+ if (!overlay->popup)
+ return;
+
+ e_popup_layer_set(overlay->popup, TILING_POPUP_LAYER);
+ overlay->obj = edje_object_add(overlay->popup->evas);
+ _theme_edje_object_set(overlay->obj, "modules/tiling/move/up");
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_edje_bg_object_set(overlay->popup,
+ overlay->obj);
+ evas_object_show(overlay->obj);
+ e_popup_move_resize(overlay->popup,
+ extra->expected.x + extra->expected.w/2
+ - ew/2
+ - overlay->popup->zone->x,
+ extra->expected.y - eh/2
+ - overlay->popup->zone->y,
+ ew,
+ eh);
+ evas_object_resize(overlay->obj, ew, eh);
+
+ e_popup_show(overlay->popup);
+ }
+ } else if (overlay->popup) {
+ if (overlay->obj) {
+ evas_object_del(overlay->obj);
+ overlay->obj = NULL;
+ }
+ if (overlay->popup) {
+ e_object_del(E_OBJECT(overlay->popup));
+ overlay->popup = NULL;
+ }
+ }
+
+ /* move down */
+ overlay = &_G.move_overlays[MOVE_DOWN];
+ if ((!_G.tinfo->conf->use_rows && l->next)
+ || (_G.tinfo->conf->use_rows && (
+ stack != TILING_MAX_STACKS - 1
+ && ((stack == nb_stacks - 1 && _G.tinfo->stacks[stack]->next)
+ || (stack != nb_stacks - 1))))) {
+ if (overlay->popup) {
+ Evas_Coord ew, eh;
+
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_move(_G.move_overlays[MOVE_DOWN].popup,
+ extra->expected.x + extra->expected.w/2 - ew/2,
+ extra->expected.y + extra->expected.h - eh/2);
+ } else {
+ Evas_Coord ew, eh;
+
+ overlay->popup = e_popup_new(bd->zone, 0, 0, 1, 1);
+ if (!overlay->popup)
+ return;
+
+ e_popup_layer_set(overlay->popup, TILING_POPUP_LAYER);
+ overlay->obj = edje_object_add(overlay->popup->evas);
+ _theme_edje_object_set(overlay->obj,
+ "modules/tiling/move/down");
+ edje_object_size_min_calc(overlay->obj, &ew, &eh);
+ e_popup_edje_bg_object_set(overlay->popup,
+ overlay->obj);
+ evas_object_show(overlay->obj);
+ e_popup_move_resize(overlay->popup,
+ extra->expected.x + extra->expected.w/2
+ - ew/2
+ - overlay->popup->zone->x,
+ extra->expected.y + extra->expected.h - eh/2
+ - overlay->popup->zone->y,
+ ew,
+ eh);
+ evas_object_resize(overlay->obj, ew, eh);
+
+ e_popup_show(overlay->popup);
+ }
+ } else if (overlay->popup) {
+ if (overlay->obj) {
+ evas_object_del(overlay->obj);
+ overlay->obj = NULL;
+ }
+ if (overlay->popup) {
+ e_object_del(E_OBJECT(overlay->popup));
+ overlay->popup = NULL;
+ }
+ }
+}
+
+static void
+_move_up_cols(void)
+{
+ E_Border *bd_1 = _G.focused_bd,
+ *bd_2 = NULL;
+ Border_Extra *extra_1 = NULL,
+ *extra_2 = NULL;
+ Eina_List *l_1 = NULL,
+ *l_2 = NULL;
+ int stack;
+
+ stack = get_stack(_G.focused_bd);
+ if (stack < 0)
+ return;
+
+ if (_G.tinfo->stacks[stack]->data == _G.focused_bd)
+ return;
+
+ l_1 = eina_list_data_find_list(_G.tinfo->stacks[stack], bd_1);
+ if (!l_1 || !l_1->prev)
+ return;
+ l_2 = l_1->prev;
+ bd_2 = l_2->data;
+
+ extra_1 = eina_hash_find(_G.border_extras, &bd_1);
+ if (!extra_1) {
+ ERR("No extra for %p", bd_1);
+ return;
+ }
+ extra_2 = eina_hash_find(_G.border_extras, &bd_2);
+ if (!extra_2) {
+ ERR("No extra for %p", bd_2);
+ return;
+ }
+
+ l_1->data = bd_2;
+ l_2->data = bd_1;
+
+ extra_1->expected.y = extra_2->expected.y;
+ extra_2->expected.y += extra_1->expected.h;
+
+ _e_border_move(bd_1,
+ extra_1->expected.x,
+ extra_1->expected.y);
+ _e_border_move(bd_2,
+ extra_2->expected.x,
+ extra_2->expected.y);
+
+ _check_moving_anims(bd_1, extra_1, stack);
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra_1->expected.x + extra_1->expected.w/2,
+ extra_1->expected.y + extra_1->expected.h/2);
+}
+
+static void
+_move_down_cols(void)
+{
+ E_Border *bd_1 = _G.focused_bd,
+ *bd_2 = NULL;
+ Border_Extra *extra_1 = NULL,
+ *extra_2 = NULL;
+ Eina_List *l_1 = NULL,
+ *l_2 = NULL;
+ int stack;
+
+ stack = get_stack(_G.focused_bd);
+ if (stack < 0)
+ return;
+
+ l_1 = eina_list_data_find_list(_G.tinfo->stacks[stack], bd_1);
+ if (!l_1 || !l_1->next)
+ return;
+ l_2 = l_1->next;
+ bd_2 = l_2->data;
+
+ extra_1 = eina_hash_find(_G.border_extras, &bd_1);
+ if (!extra_1) {
+ ERR("No extra for %p", bd_1);
+ return;
+ }
+ extra_2 = eina_hash_find(_G.border_extras, &bd_2);
+ if (!extra_2) {
+ ERR("No extra for %p", bd_2);
+ return;
+ }
+
+ l_1->data = bd_2;
+ l_2->data = bd_1;
+
+ extra_2->expected.y = extra_1->expected.y;
+ extra_1->expected.y += extra_2->expected.h;
+
+ _e_border_move(bd_1,
+ extra_1->expected.x,
+ extra_1->expected.y);
+ _e_border_move(bd_2,
+ extra_2->expected.x,
+ extra_2->expected.y);
+
+ _check_moving_anims(bd_1, extra_1, stack);
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra_1->expected.x + extra_1->expected.w/2,
+ extra_1->expected.y + extra_1->expected.h/2);
+}
+
+static void
+_move_left_cols(void)
+{
+ E_Border *bd = _G.focused_bd;
+ Border_Extra *extra;
+ int stack;
+
+ stack = get_stack(_G.focused_bd);
+ if (stack <= 0)
+ return;
+
+
+ EINA_LIST_REMOVE(_G.tinfo->stacks[stack], bd);
+ EINA_LIST_APPEND(_G.tinfo->stacks[stack - 1], bd);
+
+ if (!_G.tinfo->stacks[stack]) {
+ int x, y, w, h;
+ int width = 0;
+ int nb_stacks;
+
+ /* Remove stack */
+ nb_stacks = get_stack_count();
+
+ e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
+
+ for (int i = stack; i < nb_stacks; i++) {
+ _G.tinfo->stacks[i] = _G.tinfo->stacks[i+1];
+ }
+ _G.tinfo->stacks[nb_stacks] = NULL;
+ for (int i = 0; i < nb_stacks; i++) {
+
+ width = w / (nb_stacks - i);
+
+ _set_stack_geometry(i, x, width);
+
+ w -= width;
+ x += width;
+ }
+ _reorganize_stack(stack - 1);
+ } else {
+ _reorganize_stack(stack);
+ _reorganize_stack(stack - 1);
+ }
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+
+ _check_moving_anims(bd, extra, stack - 1);
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra->expected.x + extra->expected.w/2,
+ extra->expected.y + extra->expected.h/2);
+}
+
+static void
+_move_right_cols(void)
+{
+ E_Border *bd = _G.focused_bd;
+ int stack;
+ int nb_stacks;
+ Border_Extra *extra;
+
+ stack = get_stack(bd);
+ if (stack == TILING_MAX_STACKS - 1)
+ return;
+
+ nb_stacks = get_stack_count();
+ if (stack == nb_stacks - 1 && !_G.tinfo->stacks[stack]->next)
+ return;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+
+ EINA_LIST_REMOVE(_G.tinfo->stacks[stack], bd);
+ EINA_LIST_APPEND(_G.tinfo->stacks[stack + 1], bd);
+
+ if (_G.tinfo->stacks[stack] && _G.tinfo->stacks[stack + 1]->next) {
+ _reorganize_stack(stack);
+ _reorganize_stack(stack + 1);
+ _check_moving_anims(bd, extra, stack + 1);
+ } else
+ if (_G.tinfo->stacks[stack]) {
+ /* Add stack */
+ int x, y, w, h;
+ int width = 0;
+
+ _reorganize_stack(stack);
+
+ e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
+
+ for (int i = 0; i < nb_stacks; i++) {
+
+ width = w / (nb_stacks + 1 - i);
+
+ _set_stack_geometry(i, x, width);
+
+ w -= width;
+ x += width;
+ }
+
+ _G.tinfo->pos[nb_stacks] = x;
+ _G.tinfo->size[nb_stacks] = width;
+ extra->expected.x = x;
+ extra->expected.y = y;
+ extra->expected.w = width;
+ extra->expected.h = h;
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND | E_MAXIMIZE_VERTICAL);
+
+ if (nb_stacks + 1 > _G.tinfo->conf->nb_stacks) {
+ _G.tinfo->conf->nb_stacks = nb_stacks + 1;
+ e_config_save_queue();
+ }
+ _check_moving_anims(bd, extra, stack + 1);
+ } else {
+ int x, y, w, h;
+ int width;
+
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone, &x, &y, &w, &h);
+ for (int i = stack; i < nb_stacks; i++) {
+ _G.tinfo->stacks[i] = _G.tinfo->stacks[i + 1];
+ }
+ nb_stacks--;
+ for (int i = 0; i < nb_stacks; i++) {
+ width = w / (nb_stacks - i);
+
+ _set_stack_geometry(i, x, width);
+
+ w -= width;
+ x += width;
+ }
+ _G.tinfo->stacks[nb_stacks] = NULL;
+ _G.tinfo->pos[nb_stacks] = 0;
+ _G.tinfo->size[nb_stacks] = 0;
+ _reorganize_stack(stack);
+ _check_moving_anims(bd, extra, stack);
+ }
+
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra->expected.x + extra->expected.w/2,
+ extra->expected.y + extra->expected.h/2);
+}
+
+static void
+_move_left_rows(void)
+{
+ E_Border *bd_1 = _G.focused_bd,
+ *bd_2 = NULL;
+ Border_Extra *extra_1 = NULL,
+ *extra_2 = NULL;
+ Eina_List *l_1 = NULL,
+ *l_2 = NULL;
+ int stack;
+
+ stack = get_stack(_G.focused_bd);
+ if (stack < 0)
+ return;
+
+ if (_G.tinfo->stacks[stack]->data == _G.focused_bd)
+ return;
+
+ l_1 = eina_list_data_find_list(_G.tinfo->stacks[stack], bd_1);
+ if (!l_1 || !l_1->prev)
+ return;
+ l_2 = l_1->prev;
+ bd_2 = l_2->data;
+
+ extra_1 = eina_hash_find(_G.border_extras, &bd_1);
+ if (!extra_1) {
+ ERR("No extra for %p", bd_1);
+ return;
+ }
+ extra_2 = eina_hash_find(_G.border_extras, &bd_2);
+ if (!extra_2) {
+ ERR("No extra for %p", bd_2);
+ return;
+ }
+
+ l_1->data = bd_2;
+ l_2->data = bd_1;
+
+ extra_1->expected.x = extra_2->expected.x;
+ extra_2->expected.x += extra_1->expected.w;
+
+ _e_border_move(bd_1,
+ extra_1->expected.x,
+ extra_1->expected.y);
+ _e_border_move(bd_2,
+ extra_2->expected.x,
+ extra_2->expected.y);
+
+ _check_moving_anims(bd_1, extra_1, stack);
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra_1->expected.x + extra_1->expected.w/2,
+ extra_1->expected.y + extra_1->expected.h/2);
+}
+
+static void
+_move_right_rows(void)
+{
+ E_Border *bd_1 = _G.focused_bd,
+ *bd_2 = NULL;
+ Border_Extra *extra_1 = NULL,
+ *extra_2 = NULL;
+ Eina_List *l_1 = NULL,
+ *l_2 = NULL;
+ int stack;
+
+ stack = get_stack(_G.focused_bd);
+ if (stack < 0)
+ return;
+
+ l_1 = eina_list_data_find_list(_G.tinfo->stacks[stack], bd_1);
+ if (!l_1 || !l_1->next)
+ return;
+ l_2 = l_1->next;
+ bd_2 = l_2->data;
+
+ extra_1 = eina_hash_find(_G.border_extras, &bd_1);
+ if (!extra_1) {
+ ERR("No extra for %p", bd_1);
+ return;
+ }
+ extra_2 = eina_hash_find(_G.border_extras, &bd_2);
+ if (!extra_2) {
+ ERR("No extra for %p", bd_2);
+ return;
+ }
+
+ l_1->data = bd_2;
+ l_2->data = bd_1;
+
+ extra_2->expected.x = extra_1->expected.x;
+ extra_1->expected.x += extra_2->expected.w;
+
+ _e_border_move(bd_1,
+ extra_1->expected.x,
+ extra_1->expected.y);
+ _e_border_move(bd_2,
+ extra_2->expected.x,
+ extra_2->expected.y);
+
+ _check_moving_anims(bd_1, extra_1, stack);
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra_1->expected.x + extra_1->expected.w/2,
+ extra_1->expected.y + extra_1->expected.h/2);
+}
+
+static void
+_move_up_rows(void)
+{
+ E_Border *bd = _G.focused_bd;
+ Border_Extra *extra;
+ int stack;
+
+ stack = get_stack(_G.focused_bd);
+ if (stack <= 0)
+ return;
+
+
+ EINA_LIST_REMOVE(_G.tinfo->stacks[stack], bd);
+ EINA_LIST_APPEND(_G.tinfo->stacks[stack - 1], bd);
+
+ if (!_G.tinfo->stacks[stack]) {
+ int x, y, w, h;
+ int nb_stacks;
+
+ /* Remove stack */
+ nb_stacks = get_stack_count();
+
+ e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
+
+ for (int i = stack; i < nb_stacks; i++) {
+ _G.tinfo->stacks[i] = _G.tinfo->stacks[i+1];
+ }
+ _G.tinfo->stacks[nb_stacks] = NULL;
+ for (int i = 0; i < nb_stacks; i++) {
+ int height = 0;
+
+ height = h / (nb_stacks - i);
+
+ _set_stack_geometry(i, y, height);
+
+ h -= height;
+ y += height;
+ }
+ _reorganize_stack(stack - 1);
+ } else {
+ _reorganize_stack(stack);
+ _reorganize_stack(stack - 1);
+ }
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+
+ _check_moving_anims(bd, extra, stack - 1);
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra->expected.x + extra->expected.w/2,
+ extra->expected.y + extra->expected.h/2);
+}
+
+static void
+_move_down_rows(void)
+{
+ E_Border *bd = _G.focused_bd;
+ int stack;
+ int nb_stacks;
+ Border_Extra *extra;
+
+ stack = get_stack(bd);
+ if (stack == TILING_MAX_STACKS - 1)
+ return;
+
+ nb_stacks = get_stack_count();
+ if (stack == nb_stacks - 1 && !_G.tinfo->stacks[stack]->next)
+ return;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+
+ EINA_LIST_REMOVE(_G.tinfo->stacks[stack], bd);
+ EINA_LIST_APPEND(_G.tinfo->stacks[stack + 1], bd);
+
+ if (_G.tinfo->stacks[stack] && _G.tinfo->stacks[stack + 1]->next) {
+ _reorganize_stack(stack);
+ _reorganize_stack(stack + 1);
+ _check_moving_anims(bd, extra, stack + 1);
+ } else
+ if (_G.tinfo->stacks[stack]) {
+ /* Add stack */
+ int x, y, w, h;
+ int height = 0;
+
+ _reorganize_stack(stack);
+
+ e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
+
+ for (int i = 0; i < nb_stacks; i++) {
+
+ height = h / (nb_stacks + 1 - i);
+
+ _set_stack_geometry(i, y, height);
+
+ h -= height;
+ y += height;
+ }
+
+ _G.tinfo->pos[nb_stacks] = y;
+ _G.tinfo->size[nb_stacks] = height;
+ extra->expected.x = x;
+ extra->expected.y = y;
+ extra->expected.w = w;
+ extra->expected.h = height;
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND | E_MAXIMIZE_HORIZONTAL);
+
+ if (nb_stacks + 1 > _G.tinfo->conf->nb_stacks) {
+ _G.tinfo->conf->nb_stacks = nb_stacks + 1;
+ e_config_save_queue();
+ }
+ _check_moving_anims(bd, extra, stack + 1);
+ } else {
+ int x, y, w, h;
+
+ e_zone_useful_geometry_get(_G.tinfo->desk->zone, &x, &y, &w, &h);
+ for (int i = stack; i < nb_stacks; i++) {
+ _G.tinfo->stacks[i] = _G.tinfo->stacks[i + 1];
+ }
+ nb_stacks--;
+ for (int i = 0; i < nb_stacks; i++) {
+ int height;
+
+ height = h / (nb_stacks - i);
+
+ _set_stack_geometry(i, y, height);
+
+ h -= height;
+ y += height;
+ }
+ _G.tinfo->stacks[nb_stacks] = NULL;
+ _G.tinfo->pos[nb_stacks] = 0;
+ _G.tinfo->size[nb_stacks] = 0;
+ _reorganize_stack(stack);
+ _check_moving_anims(bd, extra, stack);
+ }
+
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ extra->expected.x + extra->expected.w/2,
+ extra->expected.y + extra->expected.h/2);
+}
+
+static Eina_Bool
+move_key_down(void *data,
+ int type,
+ void *event)
+{
+ Ecore_Event_Key *ev = event;
+
+ if (ev->event_window != _G.action_input_win)
+ return ECORE_CALLBACK_PASS_ON;
+
+ /* reset timer */
+ ecore_timer_delay(_G.action_timer, TILING_OVERLAY_TIMEOUT
+ - ecore_timer_pending_get(_G.action_timer));
+
+ if ((strcmp(ev->key, "Up") == 0)
+ || (strcmp(ev->key, "k") == 0))
+ {
+ if (_G.tinfo->conf->use_rows)
+ _move_up_rows();
+ else
+ _move_up_cols();
+ return ECORE_CALLBACK_PASS_ON;
+ } else if ((strcmp(ev->key, "Down") == 0)
+ || (strcmp(ev->key, "j") == 0))
+ {
+ if (_G.tinfo->conf->use_rows)
+ _move_down_rows();
+ else
+ _move_down_cols();
+ return ECORE_CALLBACK_PASS_ON;
+ } else if ((strcmp(ev->key, "Left") == 0)
+ || (strcmp(ev->key, "h") == 0))
+ {
+ if (_G.tinfo->conf->use_rows)
+ _move_left_rows();
+ else
+ _move_left_cols();
+ return ECORE_CALLBACK_PASS_ON;
+ } else if ((strcmp(ev->key, "Right") == 0)
+ || (strcmp(ev->key, "l") == 0))
+ {
+ if (_G.tinfo->conf->use_rows)
+ _move_right_rows();
+ else
+ _move_right_cols();
+ return ECORE_CALLBACK_PASS_ON;
+ }
+
+ if (strcmp(ev->key, "Return") == 0)
+ goto stop;
+ if (strcmp(ev->key, "Escape") == 0)
+ goto stop; /* TODO: fallback */
+
+ return ECORE_CALLBACK_PASS_ON;
+stop:
+ end_special_input();
+ return ECORE_CALLBACK_DONE;
+}
+
+static void
+_e_mod_action_move_cb(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk;
+ E_Border *focused_bd;
+ Ecore_X_Window parent;
+
+ desk = get_current_desk();
+ if (!desk)
+ return;
+
+ focused_bd = e_border_focused_get();
+ if (!focused_bd || focused_bd->desk != desk)
+ return;
+
+ check_tinfo(desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ _G.focused_bd = focused_bd;
+
+ _G.input_mode = INPUT_MODE_MOVING;
+
+ /* Get input */
+ parent = focused_bd->zone->container->win;
+ _G.action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
+ if (!_G.action_input_win) {
+ end_special_input();
+ return;
+ }
+
+ ecore_x_window_show(_G.action_input_win);
+ if (!e_grabinput_get(_G.action_input_win, 0, _G.action_input_win)) {
+ end_special_input();
+ return;
+ }
+ _G.action_timer = ecore_timer_add(TILING_OVERLAY_TIMEOUT,
+ _timeout_cb, NULL);
+
+ _G.handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
+ move_key_down, NULL);
+ _check_moving_anims(focused_bd, NULL, -1);
+}
+
+/* }}} */
+/* Adjust Transitions {{{ */
+
+static void
+_transition_overlays_free_cb(void *data)
+{
+ transition_overlay_t *trov = data;
+
+ if (trov->overlay.obj) {
+ evas_object_del(trov->overlay.obj);
+ trov->overlay.obj = NULL;
+ }
+ if (trov->overlay.popup) {
+ e_object_del(E_OBJECT(trov->overlay.popup));
+ trov->overlay.popup = NULL;
+ }
+ if (trov != _G.transition_overlay) {
+ E_FREE(trov);
+ }
+}
+
+static void
+_transition_move_cols(tiling_move_t direction)
+{
+ int delta = TILING_RESIZE_STEP;
+ int stack;
+ E_Popup *popup = NULL;
+
+ if (!_G.transition_overlay)
+ return;
+
+ stack = _G.transition_overlay->stack;
+
+ if (_G.transition_overlay->bd) {
+ Eina_List *l = NULL;
+ E_Border *bd = _G.transition_overlay->bd,
+ *nextbd = NULL;
+ Border_Extra *extra = NULL,
+ *nextextra = NULL;
+ int min_height = 0;
+
+ l = eina_list_data_find_list(_G.tinfo->stacks[stack], bd);
+ if (!l) {
+ ERR("unable to bd %p in stack %d", bd, stack);
+ return;
+ }
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+ nextbd = l->next->data;
+ nextextra = eina_hash_find(_G.border_extras, &nextbd);
+ if (!nextextra) {
+ ERR("No extra for %p", nextbd);
+ return;
+ }
+
+ if (direction == MOVE_UP) {
+ delta *= -1;
+ }
+
+ nextbd = l->next->data;
+ min_height = MAX(nextbd->client.icccm.base_h, 1);
+
+ if (nextextra->expected.h - delta < min_height)
+ delta = nextextra->expected.h - min_height;
+
+ nextextra->expected.y += delta;
+ nextextra->expected.h -= delta;
+ _e_border_move_resize(nextbd,
+ nextextra->expected.x,
+ nextextra->expected.y,
+ nextextra->expected.w,
+ nextextra->expected.h);
+
+ extra->expected.h += delta;
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+
+ popup = _G.transition_overlay->overlay.popup;
+ e_popup_move(popup, popup->x, popup->y + delta);
+ } else {
+
+ if (stack == TILING_MAX_STACKS || !_G.tinfo->stacks[stack + 1]) {
+ return;
+ }
+ if (direction == MOVE_LEFT) {
+ delta *= -1;
+ }
+
+ if (delta + 1 > _G.tinfo->size[stack + 1])
+ delta = _G.tinfo->size[stack + 1] - 1;
+
+ _move_resize_stack(stack, 0, delta);
+ _move_resize_stack(stack+1, delta, -delta);
+
+ popup = _G.transition_overlay->overlay.popup;
+ e_popup_move(popup, popup->x + delta, popup->y);
+ }
+}
+
+static void
+_transition_move_rows(tiling_move_t direction)
+{
+ int delta = TILING_RESIZE_STEP;
+ int stack;
+ E_Popup *popup = NULL;
+
+ if (!_G.transition_overlay)
+ return;
+
+ stack = _G.transition_overlay->stack;
+
+ if (_G.transition_overlay->bd) {
+ Eina_List *l = NULL;
+ E_Border *bd = _G.transition_overlay->bd,
+ *nextbd = NULL;
+ Border_Extra *extra = NULL,
+ *nextextra = NULL;
+ int min_width = 0;
+
+ l = eina_list_data_find_list(_G.tinfo->stacks[stack], bd);
+ if (!l) {
+ ERR("unable to bd %p in stack %d", bd, stack);
+ return;
+ }
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+ nextbd = l->next->data;
+ nextextra = eina_hash_find(_G.border_extras, &nextbd);
+ if (!nextextra) {
+ ERR("No extra for %p", nextbd);
+ return;
+ }
+
+ if (direction == MOVE_LEFT) {
+ delta *= -1;
+ }
+
+ nextbd = l->next->data;
+ min_width = MAX(nextbd->client.icccm.base_w, 1);
+
+ if (nextextra->expected.w - delta < min_width)
+ delta = nextextra->expected.w - min_width;
+
+ nextextra->expected.x += delta;
+ nextextra->expected.w -= delta;
+ _e_border_move_resize(nextbd,
+ nextextra->expected.x,
+ nextextra->expected.y,
+ nextextra->expected.w,
+ nextextra->expected.h);
+
+ extra->expected.w += delta;
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+
+ popup = _G.transition_overlay->overlay.popup;
+ e_popup_move(popup, popup->x + delta, popup->y);
+ } else {
+
+ if (stack == TILING_MAX_STACKS || !_G.tinfo->stacks[stack + 1]) {
+ return;
+ }
+ if (direction == MOVE_UP) {
+ delta *= -1;
+ }
+
+ if (delta + 1 > _G.tinfo->size[stack + 1])
+ delta = _G.tinfo->size[stack + 1] - 1;
+
+ _move_resize_stack(stack, 0, delta);
+ _move_resize_stack(stack+1, delta, -delta);
+
+ popup = _G.transition_overlay->overlay.popup;
+ e_popup_move(popup, popup->x, popup->y + delta);
+ }
+}
+
+static Eina_Bool
+_transition_overlay_key_down(void *data,
+ int type,
+ void *event)
+{
+ Ecore_Event_Key *ev = event;
+
+ if (ev->event_window != _G.action_input_win)
+ return ECORE_CALLBACK_PASS_ON;
+
+ if (strcmp(ev->key, "Return") == 0)
+ goto stop;
+ if (strcmp(ev->key, "Escape") == 0)
+ goto stop;
+
+ /* reset timer */
+ ecore_timer_delay(_G.action_timer, TILING_OVERLAY_TIMEOUT
+ - ecore_timer_pending_get(_G.action_timer));
+
+ if (_G.transition_overlay) {
+ DBG("ev->key='%s'; %p %d", ev->key,
+ _G.transition_overlay->bd, _G.tinfo->conf->use_rows);
+ if ((strcmp(ev->key, "Up") == 0)
+ || (strcmp(ev->key, "k") == 0))
+ {
+ if (_G.transition_overlay->bd && !_G.tinfo->conf->use_rows) {
+ _transition_move_cols(MOVE_UP);
+ return ECORE_CALLBACK_PASS_ON;
+ } else
+ if (!_G.transition_overlay->bd && _G.tinfo->conf->use_rows) {
+ _transition_move_rows(MOVE_UP);
+ return ECORE_CALLBACK_PASS_ON;
+ }
+ } else
+ if ((strcmp(ev->key, "Down") == 0)
+ || (strcmp(ev->key, "j") == 0))
+ {
+ if (_G.transition_overlay->bd && !_G.tinfo->conf->use_rows) {
+ _transition_move_cols(MOVE_DOWN);
+ return ECORE_CALLBACK_PASS_ON;
+ } else
+ if (!_G.transition_overlay->bd && _G.tinfo->conf->use_rows) {
+ _transition_move_rows(MOVE_DOWN);
+ return ECORE_CALLBACK_PASS_ON;
+ }
+ } else
+ if ((strcmp(ev->key, "Left") == 0)
+ || (strcmp(ev->key, "h") == 0))
+ {
+ if (!_G.transition_overlay->bd && !_G.tinfo->conf->use_rows) {
+ _transition_move_cols(MOVE_LEFT);
+ return ECORE_CALLBACK_PASS_ON;
+ } else
+ if (_G.transition_overlay->bd && _G.tinfo->conf->use_rows) {
+ _transition_move_rows(MOVE_LEFT);
+ return ECORE_CALLBACK_PASS_ON;
+ }
+ } else
+ if ((strcmp(ev->key, "Right") == 0)
+ || (strcmp(ev->key, "l") == 0))
+ {
+ if (!_G.transition_overlay->bd && !_G.tinfo->conf->use_rows) {
+ _transition_move_cols(MOVE_RIGHT);
+ return ECORE_CALLBACK_PASS_ON;
+ } else
+ if (_G.transition_overlay->bd && _G.tinfo->conf->use_rows) {
+ _transition_move_rows(MOVE_RIGHT);
+ return ECORE_CALLBACK_PASS_ON;
+ }
+ }
+
+ return ECORE_CALLBACK_RENEW;
+ } else {
+ if (strcmp(ev->key, "Backspace") == 0) {
+ char *key = _G.keys;
+
+ while (*key)
+ key++;
+ *key = '\0';
+ return ECORE_CALLBACK_RENEW;
+ }
+ if (ev->key[0] && !ev->key[1] && strchr(tiling_g.config->keyhints,
+ ev->key[1]))
+ {
+ transition_overlay_t *trov = NULL;
+ E_Border *bd = NULL;
+ Border_Extra *extra = NULL;
+ Evas_Coord ew, eh;
+ char *key = _G.keys;
+
+ while (*key)
+ key++;
+ *key++ = ev->key[0];
+ *key = '\0';
+
+ trov = eina_hash_find(_G.overlays, _G.keys);
+ if (!trov) {
+ return ECORE_CALLBACK_RENEW;
+ }
+ bd = trov->bd;
+
+ _G.transition_overlay = trov;
+ eina_hash_free(_G.overlays);
+ _G.overlays = NULL;
+
+ if (bd) {
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ goto stop;
+ }
+ }
+ if (!trov->overlay.popup) {
+ trov->overlay.popup = e_popup_new(_G.tinfo->desk->zone,
+ 0, 0, 1, 1);
+ e_popup_layer_set(trov->overlay.popup, TILING_POPUP_LAYER);
+ }
+ if (!trov->overlay.obj) {
+ trov->overlay.obj =
+ edje_object_add(trov->overlay.popup->evas);
+ }
+ if ((bd && !_G.tinfo->conf->use_rows)
+ || (!bd && _G.tinfo->conf->use_rows)) {
+ _theme_edje_object_set(trov->overlay.obj,
+ "modules/tiling/transition/horizontal");
+ } else {
+ _theme_edje_object_set(trov->overlay.obj,
+ "modules/tiling/transition/vertical");
+ }
+
+ edje_object_size_min_calc(trov->overlay.obj, &ew, &eh);
+ e_popup_edje_bg_object_set(trov->overlay.popup,
+ trov->overlay.obj);
+ evas_object_show(trov->overlay.obj);
+ if (bd) {
+ if (_G.tinfo->conf->use_rows) {
+ e_popup_move_resize(trov->overlay.popup,
+ (extra->expected.x - trov->overlay.popup->zone->x +
+ extra->expected.w - (ew / 2)),
+ (extra->expected.y - trov->overlay.popup->zone->y +
+ ((extra->expected.h - eh) / 2)),
+ ew, eh);
+ } else {
+ e_popup_move_resize(trov->overlay.popup,
+ (extra->expected.x - trov->overlay.popup->zone->x +
+ ((extra->expected.w - ew) / 2)),
+ (extra->expected.y - trov->overlay.popup->zone->y +
+ extra->expected.h - (eh / 2)),
+ ew, eh);
+ }
+ } else {
+ if (_G.tinfo->conf->use_rows) {
+ e_popup_move_resize(trov->overlay.popup,
+ (trov->overlay.popup->zone->w/2 - ew/2),
+ (_G.tinfo->pos[trov->stack]
+ + _G.tinfo->size[trov->stack]
+ - trov->overlay.popup->zone->y - eh/2),
+ ew, eh);
+ } else {
+ e_popup_move_resize(trov->overlay.popup,
+ (_G.tinfo->pos[trov->stack]
+ + _G.tinfo->size[trov->stack]
+ - trov->overlay.popup->zone->x - ew/2),
+ (trov->overlay.popup->zone->h/2 - eh/2),
+ ew, eh);
+ }
+ }
+ evas_object_resize(trov->overlay.obj, ew, eh);
+ e_popup_show(trov->overlay.popup);
+
+ return ECORE_CALLBACK_RENEW;
+ }
+ }
+
+stop:
+ end_special_input();
+ return ECORE_CALLBACK_DONE;
+}
+
+static void
+_do_transition_overlay(void)
+{
+ int nb_transitions;
+ Ecore_X_Window parent;
+ int hints_len;
+ int key_len;
+ int n = 0;
+ int nmax;
+
+ end_special_input();
+
+ nb_transitions = get_transition_count();
+ if (nb_transitions < 1) {
+ return;
+ }
+
+ _G.input_mode = INPUT_MODE_TRANSITION;
+
+ _G.overlays = eina_hash_string_small_new(_transition_overlays_free_cb);
+ hints_len = strlen(tiling_g.config->keyhints);
+ key_len = 1;
+ nmax = hints_len;
+ if (hints_len < nb_transitions) {
+ key_len = 2;
+ nmax *= hints_len;
+ if (hints_len * hints_len < nb_transitions) {
+ key_len = 3;
+ nmax *= hints_len;
+ }
+ }
+
+
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ Eina_List *l;
+ E_Border *bd;
+
+ if (!_G.tinfo->stacks[i])
+ break;
+ EINA_LIST_FOREACH(_G.tinfo->stacks[i], l, bd) {
+ if (l->next && n < nmax) {
+ Border_Extra *extra;
+ Evas_Coord ew, eh;
+ transition_overlay_t *trov;
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ continue;
+ }
+
+ trov = E_NEW(transition_overlay_t, 1);
+
+ trov->overlay.popup = e_popup_new(bd->zone, 0, 0, 1, 1);
+ if (!trov->overlay.popup)
+ continue;
+
+ e_popup_layer_set(trov->overlay.popup, TILING_POPUP_LAYER);
+ trov->overlay.obj = edje_object_add(trov->overlay.popup->evas);
+ e_theme_edje_object_set(trov->overlay.obj,
+ "base/theme/borders",
+ "e/widgets/border/default/resize");
+
+ switch (key_len) {
+ case 1:
+ trov->key[0] = tiling_g.config->keyhints[n];
+ trov->key[1] = '\0';
+ break;
+ case 2:
+ trov->key[0] = tiling_g.config->keyhints[n / hints_len];
+ trov->key[1] = tiling_g.config->keyhints[n % hints_len];
+ trov->key[2] = '\0';
+ break;
+ case 3:
+ trov->key[0] = tiling_g.config->keyhints[n / hints_len / hints_len];
+ trov->key[0] = tiling_g.config->keyhints[n / hints_len];
+ trov->key[1] = tiling_g.config->keyhints[n % hints_len];
+ trov->key[2] = '\0';
+ break;
+ }
+ n++;
+ trov->stack = i;
+ trov->bd = bd;
+
+ eina_hash_add(_G.overlays, trov->key, trov);
+ edje_object_part_text_set(trov->overlay.obj,
+ "e.text.label",
+ trov->key);
+ edje_object_size_min_calc(trov->overlay.obj, &ew, &eh);
+ evas_object_move(trov->overlay.obj, 0, 0);
+ evas_object_resize(trov->overlay.obj, ew, eh);
+ evas_object_show(trov->overlay.obj);
+ e_popup_edje_bg_object_set(trov->overlay.popup,
+ trov->overlay.obj);
+
+ evas_object_show(trov->overlay.obj);
+ e_popup_show(trov->overlay.popup);
+
+ if (_G.tinfo->conf->use_rows) {
+ e_popup_move_resize(trov->overlay.popup,
+ (extra->expected.x - trov->overlay.popup->zone->x +
+ extra->expected.w - (ew / 2)),
+ (extra->expected.y - trov->overlay.popup->zone->y +
+ ((extra->expected.h - eh) / 2)),
+ ew, eh);
+ } else {
+ e_popup_move_resize(trov->overlay.popup,
+ (extra->expected.x - trov->overlay.popup->zone->x +
+ ((extra->expected.w - ew) / 2)),
+ (extra->expected.y - trov->overlay.popup->zone->y +
+ extra->expected.h - (eh / 2)),
+ ew, eh);
+ }
+
+ e_popup_show(trov->overlay.popup);
+ }
+ }
+ if (i != TILING_MAX_STACKS && _G.tinfo->stacks[i+1] && n < nmax) {
+ Evas_Coord ew, eh;
+ transition_overlay_t *trov;
+
+ trov = E_NEW(transition_overlay_t, 1);
+
+ trov->overlay.popup = e_popup_new(_G.tinfo->desk->zone,
+ 0, 0, 1, 1);
+ if (!trov->overlay.popup)
+ continue;
+
+ e_popup_layer_set(trov->overlay.popup, TILING_POPUP_LAYER);
+ trov->overlay.obj = edje_object_add(trov->overlay.popup->evas);
+ e_theme_edje_object_set(trov->overlay.obj,
+ "base/theme/borders",
+ "e/widgets/border/default/resize");
+
+ switch (key_len) {
+ case 1:
+ trov->key[0] = tiling_g.config->keyhints[n];
+ trov->key[1] = '\0';
+ break;
+ case 2:
+ trov->key[0] = tiling_g.config->keyhints[n / hints_len];
+ trov->key[1] = tiling_g.config->keyhints[n % hints_len];
+ trov->key[2] = '\0';
+ break;
+ case 3:
+ trov->key[0] = tiling_g.config->keyhints[n / hints_len / hints_len];
+ trov->key[0] = tiling_g.config->keyhints[n / hints_len];
+ trov->key[1] = tiling_g.config->keyhints[n % hints_len];
+ trov->key[2] = '\0';
+ break;
+ }
+ n++;
+ trov->stack = i;
+ trov->bd = NULL;
+
+ eina_hash_add(_G.overlays, trov->key, trov);
+ edje_object_part_text_set(trov->overlay.obj,
+ "e.text.label",
+ trov->key);
+ edje_object_size_min_calc(trov->overlay.obj, &ew, &eh);
+ evas_object_move(trov->overlay.obj, 0, 0);
+ evas_object_resize(trov->overlay.obj, ew, eh);
+ evas_object_show(trov->overlay.obj);
+ e_popup_edje_bg_object_set(trov->overlay.popup,
+ trov->overlay.obj);
+
+ evas_object_show(trov->overlay.obj);
+ e_popup_show(trov->overlay.popup);
+
+ if (_G.tinfo->conf->use_rows) {
+ e_popup_move_resize(trov->overlay.popup,
+ (trov->overlay.popup->zone->w/2 - ew/2),
+ (_G.tinfo->pos[trov->stack]
+ + _G.tinfo->size[trov->stack]
+ - trov->overlay.popup->zone->y - eh/2),
+ ew, eh);
+ } else {
+ e_popup_move_resize(trov->overlay.popup,
+ (_G.tinfo->pos[trov->stack]
+ + _G.tinfo->size[trov->stack]
+ - trov->overlay.popup->zone->x - ew/2),
+ (trov->overlay.popup->zone->h/2 - eh/2),
+ ew, eh);
+ }
+
+ e_popup_show(trov->overlay.popup);
+ }
+ }
+
+ /* Get input */
+ parent = _G.tinfo->desk->zone->container->win;
+ _G.action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
+ if (!_G.action_input_win) {
+ end_special_input();
+ return;
+ }
+
+ ecore_x_window_show(_G.action_input_win);
+ if (!e_grabinput_get(_G.action_input_win, 0, _G.action_input_win)) {
+ end_special_input();
+ return;
+ }
+ _G.action_timer = ecore_timer_add(TILING_OVERLAY_TIMEOUT,
+ _timeout_cb, NULL);
+
+ _G.keys[0] = '\0';
+ _G.handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
+ _transition_overlay_key_down,
+ NULL);
+}
+
+static void
+_e_mod_action_adjust_transitions(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk;
+
+ desk = get_current_desk();
+ if (!desk)
+ return;
+
+ check_tinfo(desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ _do_transition_overlay();
+}
+
+/* }}} */
+/* Go {{{ */
+
+static Eina_Bool
+_warp_timer(void *_)
+{
+ if (_G.warp_timer) {
+ double spd = TILING_WRAP_SPEED;
+
+ _G.old_warp_x = _G.warp_x;
+ _G.old_warp_y = _G.warp_y;
+ _G.warp_x = (_G.warp_x * (1.0 - spd)) + (_G.warp_to_x * spd);
+ _G.warp_y = (_G.warp_y * (1.0 - spd)) + (_G.warp_to_y * spd);
+
+ ecore_x_pointer_warp(_G.tinfo->desk->zone->container->win,
+ _G.warp_x, _G.warp_y);
+
+ if (abs(_G.warp_x - _G.old_warp_x) <= 1
+ && abs(_G.warp_y - _G.old_warp_y) <= 1) {
+ _G.warp_timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_RENEW;
+ }
+ _G.warp_timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_action_go(E_Border *_,
+ Border_Extra *extra_2)
+{
+ E_Border *bd = extra_2->border;
+
+ _G.warp_to_x = bd->x + (bd->w / 2);
+ _G.warp_to_y = bd->y + (bd->h / 2);
+ ecore_x_pointer_xy_get(_G.tinfo->desk->zone->container->win,
+ &_G.warp_x, &_G.warp_y);
+ e_border_focus_latest_set(bd);
+ _G.warp_timer = ecore_timer_add(0.01, _warp_timer, NULL);
+}
+
+static void
+_e_mod_action_go_cb(E_Object *obj,
+ const char *params)
+{
+ E_Desk *desk;
+
+ desk = get_current_desk();
+ if (!desk)
+ return;
+
+ check_tinfo(desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ _do_overlay(NULL, _action_go, INPUT_MODE_GOING);
+}
+
+/* }}} */
+/* Hooks {{{*/
+
+static void
+_pre_border_assign_hook(void *data,
+ E_Border *bd)
+{
+ if (tiling_g.config->show_titles)
+ return;
+
+ if (!bd) {
+ return;
+ }
+
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ if (is_floating_window(bd)) {
+ return;
+ }
+
+ if (!is_tilable(bd)) {
+ return;
+ }
+
+ if (bd->fullscreen) {
+ return;
+ }
+
+ if ((bd->bordername && strcmp(bd->bordername, "pixel"))
+ || !bd->bordername)
+ {
+ change_window_border(bd, "pixel");
+ }
+}
+
+static void _move_or_resize(E_Border *bd)
+{
+ Border_Extra *extra;
+ int stack = -1;
+
+ if (!bd) {
+ return;
+ }
+
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return;
+ }
+
+ stack = get_stack(bd);
+ if (stack < 0) {
+ return;
+ }
+
+ DBG("Resize: %p / '%s' / '%s', (%d,%d), changes(size=%d, position=%d, border=%d)"
+ " g:%dx%d+%d+%d bdname:'%s' (stack:%d%c) maximized:%s fs:%s",
+ bd, bd->client.icccm.title, bd->client.netwm.name,
+ bd->desk->x, bd->desk->y,
+ bd->changes.size, bd->changes.pos, bd->changes.border,
+ bd->w, bd->h, bd->x, bd->y, bd->bordername,
+ stack, _G.tinfo->conf->use_rows? 'r':'c',
+ (bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_NONE ? "NONE" :
+ (bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL ? "VERTICAL" :
+ (bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL ? "HORIZONTAL" :
+ "BOTH", bd->fullscreen? "true": "false");
+
+ extra = eina_hash_find(_G.border_extras, &bd);
+ if (!extra) {
+ ERR("No extra for %p", bd);
+ return;
+ }
+
+ DBG("expected: %dx%d+%d+%d",
+ extra->expected.w,
+ extra->expected.h,
+ extra->expected.x,
+ extra->expected.y);
+ DBG("delta:%dx%d,%d,%d. step:%dx%d. base:%dx%d",
+ bd->w - extra->expected.w, bd->h - extra->expected.h,
+ bd->x - extra->expected.x, bd->y - extra->expected.y,
+ bd->client.icccm.step_w, bd->client.icccm.step_h,
+ bd->client.icccm.base_w, bd->client.icccm.base_h);
+
+ if (stack == 0 && !_G.tinfo->stacks[1] && !_G.tinfo->stacks[0]->next) {
+ if (bd->maximized) {
+ extra->expected.x = bd->x;
+ extra->expected.y = bd->y;
+ extra->expected.w = bd->w;
+ extra->expected.h = bd->h;
+ } else {
+ /* TODO: what if a window doesn't want to be maximized? */
+ _e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
+ _e_border_maximize(bd, E_MAXIMIZE_EXPAND | E_MAXIMIZE_BOTH);
+ }
+ }
+ if (bd->x == extra->expected.x && bd->y == extra->expected.y
+ && bd->w == extra->expected.w && bd->h == extra->expected.h)
+ {
+ return;
+ }
+ if (bd->maximized) {
+ bool changed = false;
+
+ if (_G.tinfo->conf->use_rows) {
+ if (stack > 0 && bd->maximized & E_MAXIMIZE_VERTICAL) {
+ _e_border_unmaximize(bd, E_MAXIMIZE_VERTICAL);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ changed = true;
+ }
+ if (bd->maximized & E_MAXIMIZE_HORIZONTAL
+ && eina_list_count(_G.tinfo->stacks[stack]) > 1) {
+ _e_border_unmaximize(bd, E_MAXIMIZE_HORIZONTAL);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ changed = true;
+ }
+ } else {
+ if (stack > 0 && bd->maximized & E_MAXIMIZE_HORIZONTAL) {
+ _e_border_unmaximize(bd, E_MAXIMIZE_HORIZONTAL);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ changed = true;
+ }
+ if (bd->maximized & E_MAXIMIZE_VERTICAL
+ && eina_list_count(_G.tinfo->stacks[stack]) > 1) {
+ _e_border_unmaximize(bd, E_MAXIMIZE_VERTICAL);
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ changed = true;
+ }
+ }
+ if (changed)
+ return;
+ }
+
+ if ((bd->changes.border && bd->changes.size)
+ || bd->x <= 0 || bd->y <= 0) {
+ _e_border_move_resize(bd,
+ extra->expected.x,
+ extra->expected.y,
+ extra->expected.w,
+ extra->expected.h);
+ return;
+ }
+
+ if (abs(extra->expected.w - bd->w) >= bd->client.icccm.step_w) {
+ if (_G.tinfo->conf->use_rows)
+ _move_resize_border_in_stack(bd, extra, stack, TILING_RESIZE);
+ else
+ _move_resize_border_stack(bd, extra, stack, TILING_RESIZE);
+ }
+ if (abs(extra->expected.h - bd->h) >= bd->client.icccm.step_h) {
+ if (_G.tinfo->conf->use_rows)
+ _move_resize_border_stack(bd, extra, stack, TILING_RESIZE);
+ else
+ _move_resize_border_in_stack(bd, extra, stack, TILING_RESIZE);
+ }
+ if (extra->expected.x != bd->x) {
+ if (_G.tinfo->conf->use_rows)
+ _move_resize_border_in_stack(bd, extra, stack, TILING_MOVE);
+ else
+ _move_resize_border_stack(bd, extra, stack, TILING_MOVE);
+ }
+ if (extra->expected.y != bd->y) {
+ if (_G.tinfo->conf->use_rows)
+ _move_resize_border_stack(bd, extra, stack, TILING_MOVE);
+ else
+ _move_resize_border_in_stack(bd, extra, stack, TILING_MOVE);
+ }
+
+ if (_G.input_mode == INPUT_MODE_MOVING
+ && bd == _G.focused_bd) {
+ _check_moving_anims(bd, extra, stack);
+ }
+}
+
+static Eina_Bool
+_resize_hook(void *data, int type, E_Event_Border_Resize *event)
+{
+ E_Border *bd = event->border;
+
+ _move_or_resize(bd);
+
+ return true;
+}
+
+static Eina_Bool
+_move_hook(void *data, int type, E_Event_Border_Move*event)
+{
+ E_Border *bd = event->border;
+
+ _move_or_resize(bd);
+
+ return true;
+}
+
+static Eina_Bool
+_add_hook(void *data, int type, E_Event_Border_Add *event)
+{
+ E_Border *bd = event->border;
+ int stack = -1;
+
+ if (_G.input_mode != INPUT_MODE_NONE
+ && _G.input_mode != INPUT_MODE_MOVING
+ && _G.input_mode != INPUT_MODE_TRANSITION)
+ {
+ end_special_input();
+ }
+
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return true;
+ }
+
+ if (!is_tilable(bd)) {
+ return true;
+ }
+
+ stack = get_stack(bd);
+ if (stack >= 0) {
+ return true;
+ }
+
+ DBG("Add: %p / '%s' / '%s', (%d,%d), changes(size=%d, position=%d, border=%d)"
+ " g:%dx%d+%d+%d bdname:'%s' (stack:%d%c) maximized:%s fs:%s",
+ bd, bd->client.icccm.title, bd->client.netwm.name,
+ bd->desk->x, bd->desk->y,
+ bd->changes.size, bd->changes.pos, bd->changes.border,
+ bd->w, bd->h, bd->x, bd->y, bd->bordername,
+ stack, _G.tinfo->conf->use_rows? 'r':'c',
+ (bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_NONE ? "NONE" :
+ (bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL ? "VERTICAL" :
+ (bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL ? "HORIZONTAL" :
+ "BOTH", bd->fullscreen? "true": "false");
+
+ _add_border(bd);
+
+ return true;
+}
+
+static Eina_Bool
+_remove_hook(void *data, int type, E_Event_Border_Remove *event)
+{
+ E_Border *bd = event->border;
+
+ end_special_input();
+
+ if (_G.currently_switching_desktop)
+ return EINA_TRUE;
+
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf)
+ return EINA_TRUE;
+
+ if (EINA_LIST_IS_IN(_G.tinfo->floating_windows, bd)) {
+ EINA_LIST_REMOVE(_G.tinfo->floating_windows, bd);
+ return EINA_TRUE;
+ }
+
+ _remove_border(bd);
+
+ return EINA_TRUE;
+}
+
+static bool
+_iconify_hook(void *_, int type, E_Event_Border_Iconify *event)
+{
+ E_Border *bd = event->border;
+
+ end_special_input();
+
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf)
+ return true;
+
+ if (EINA_LIST_IS_IN(_G.tinfo->floating_windows, bd)) {
+ return true;
+ }
+
+ _remove_border(bd);
+
+ return true;
+}
+
+static bool
+_uniconify_hook(void *_, int type, E_Event_Border_Uniconify *event)
+{
+ E_Border *bd = event->border;
+ int stack = -1;
+
+ if (_G.input_mode != INPUT_MODE_NONE
+ && _G.input_mode != INPUT_MODE_MOVING
+ && _G.input_mode != INPUT_MODE_TRANSITION)
+ {
+ end_special_input();
+ }
+
+ check_tinfo(bd->desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ return true;
+ }
+
+ if (!is_tilable(bd)) {
+ return true;
+ }
+
+ stack = get_stack(bd);
+ if (stack >= 0) {
+ return true;
+ }
+ _add_border(bd);
+
+ return true;
+}
+
+static Eina_Bool
+_stick_hook(void *data, int type, void *event)
+{
+ DBG("TODO");
+ return true;
+}
+
+static Eina_Bool
+_unstick_hook(void *data, int type, void *event)
+{
+ DBG("TODO");
+ return true;
+}
+
+static Eina_Bool
+_desk_show_hook(void *data, int type, void *event)
+{
+ _G.currently_switching_desktop = 0;
+
+ end_special_input();
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_desk_before_show_hook(void *data, int type, void *event)
+{
+ end_special_input();
+
+ _G.currently_switching_desktop = 1;
+
+ return EINA_TRUE;
+}
+
+static bool
+_desk_set_hook(void *data, int type, E_Event_Border_Desk_Set *ev)
+{
+ DBG("%p: from (%d,%d) to (%d,%d)", ev->border,
+ ev->desk->x, ev->desk->y,
+ ev->border->desk->x, ev->border->desk->y);
+
+ end_special_input();
+
+ check_tinfo(ev->desk);
+ if (!_G.tinfo->conf) {
+ return true;
+ }
+
+ if (get_stack(ev->border) >= 0) {
+ _remove_border(ev->border);
+ _restore_border(ev->border);
+ }
+
+ check_tinfo(ev->border->desk);
+ if (!_G.tinfo->conf) {
+ return true;
+ }
+
+ if (get_stack(ev->border) < 0)
+ _add_border(ev->border);
+
+ return true;
+}
+
+static bool
+_container_resize_hook(void *_, int type, E_Event_Container_Resize *ev)
+{
+ Eina_List *l;
+ E_Zone *zone;
+
+ EINA_LIST_FOREACH(ev->container->zones, l, zone) {
+ for (int x = 0; x < zone->desk_x_count; x++)
+ {
+ for (int y = 0; y < zone->desk_y_count; y++) {
+ E_Desk *desk = zone->desks[x + (y * zone->desk_x_count)];
+ Eina_List *wins = NULL;
+ E_Border *bd;
+
+ check_tinfo(desk);
+ if (!_G.tinfo->conf || !_G.tinfo->conf->nb_stacks) {
+ continue;
+ }
+
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ EINA_LIST_FREE(_G.tinfo->stacks[i], bd) {
+ EINA_LIST_APPEND(wins, bd);
+ _restore_border(bd);
+ }
+ _G.tinfo->stacks[i] = NULL;
+ _G.tinfo->pos[i] = 0;
+ _G.tinfo->size[i] = 0;
+ }
+
+ EINA_LIST_FREE(wins, bd) {
+ _add_border(bd);
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+/* }}} */
+/* Module setup {{{*/
+
+static void
+_clear_info_hash(void *data)
+{
+ Tiling_Info *ti = data;
+
+ eina_list_free(ti->floating_windows);
+ for (int i = 0; i < TILING_MAX_STACKS; i++) {
+ eina_list_free(ti->stacks[i]);
+ ti->stacks[i] = NULL;
+ }
+ E_FREE(ti);
+}
+
+static void
+_clear_border_extras(void *data)
+{
+ Border_Extra *extra = data;
+
+ eina_stringshare_del(extra->orig.bordername);
+
+ E_FREE(extra);
+}
+
+EAPI E_Module_Api e_modapi =
+{
+ E_MODULE_API_VERSION,
+ "Tiling"
+};
+
+EAPI void *
+e_modapi_init(E_Module *m)
+{
+ char buf[PATH_MAX];
+ E_Desk *desk;
+
+ tiling_g.module = m;
+
+ if (tiling_g.log_domain < 0) {
+ tiling_g.log_domain = eina_log_domain_register("tiling", NULL);
+ if (tiling_g.log_domain < 0) {
+ EINA_LOG_CRIT("could not register log domain 'tiling'");
+ }
+ }
+
+ _G.info_hash = eina_hash_pointer_new(_clear_info_hash);
+ _G.border_extras = eina_hash_pointer_new(_clear_border_extras);
+
+ _G.pre_border_assign_hook = e_border_hook_add(
+ E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN,
+ (void (*)(void*,void*))_pre_border_assign_hook, NULL);
+
+#define HANDLER(_h, _e, _f) \
+ _h = ecore_event_handler_add(E_EVENT_##_e, \
+ (Ecore_Event_Handler_Cb) _f, \
+ NULL);
+
+ HANDLER(_G.handler_border_resize, BORDER_RESIZE, _resize_hook);
+ HANDLER(_G.handler_border_move, BORDER_MOVE, _move_hook);
+ HANDLER(_G.handler_border_add, BORDER_ADD, _add_hook);
+ HANDLER(_G.handler_border_remove, BORDER_REMOVE, _remove_hook);
+
+ HANDLER(_G.handler_border_iconify, BORDER_ICONIFY, _iconify_hook);
+ HANDLER(_G.handler_border_uniconify, BORDER_UNICONIFY, _uniconify_hook);
+ HANDLER(_G.handler_border_stick, BORDER_STICK, _stick_hook);
+ HANDLER(_G.handler_border_unstick, BORDER_UNSTICK, _unstick_hook);
+
+ HANDLER(_G.handler_desk_show, DESK_SHOW, _desk_show_hook);
+ HANDLER(_G.handler_desk_before_show, DESK_BEFORE_SHOW, _desk_before_show_hook);
+ HANDLER(_G.handler_desk_set, BORDER_DESK_SET, _desk_set_hook);
+ HANDLER(_G.handler_container_resize, CONTAINER_RESIZE, _container_resize_hook);
+#undef HANDLER
+
+#define ACTION_ADD(_act, _cb, _title, _value) \
+ { \
+ E_Action *_action = _act; \
+ const char *_name = _value; \
+ if ((_action = e_action_add(_name))) { \
+ _action->func.go = _cb; \
+ e_action_predef_name_set(_("Tiling"), _(_title), _name, \
+ NULL, NULL, 0); \
+ } \
+ }
+
+ /* Module's actions */
+ ACTION_ADD(_G.act_togglefloat, _e_mod_action_toggle_floating_cb,
+ "Toggle floating", "toggle_floating");
+ ACTION_ADD(_G.act_addstack, _e_mod_action_add_stack_cb,
+ "Add a stack", "add_stack");
+ ACTION_ADD(_G.act_removestack, _e_mod_action_remove_stack_cb,
+ "Remove a stack", "remove_stack");
+ ACTION_ADD(_G.act_tg_stack, _e_mod_action_tg_stack_cb,
+ "Toggle between rows and columns", "tg_cols_rows");
+ ACTION_ADD(_G.act_swap, _e_mod_action_swap_cb,
+ "Swap a window with an other", "swap");
+ ACTION_ADD(_G.act_move, _e_mod_action_move_cb,
+ "Move window", "move");
+ ACTION_ADD(_G.act_adjusttransitions, _e_mod_action_adjust_transitions,
+ "Adjust transitions", "adjust_transitions");
+ ACTION_ADD(_G.act_go, _e_mod_action_go_cb,
+ "Focus a particular window", "go");
+#undef ACTION_ADD
+
+ /* Configuration entries */
+ snprintf(_G.edj_path, sizeof(_G.edj_path),"%s/e-module-tiling.edj",
+ e_module_dir_get(m));
+ e_configure_registry_category_add("windows", 50, _("Windows"), NULL,
+ "preferences-system-windows");
+ e_configure_registry_item_add("windows/tiling", 150, _("Tiling"),
+ NULL, _G.edj_path,
+ e_int_config_tiling_module);
+
+ /* Configuration itself */
+ _G.config_edd = E_CONFIG_DD_NEW("Tiling_Config", Config);
+ _G.vdesk_edd = E_CONFIG_DD_NEW("Tiling_Config_VDesk",
+ struct _Config_vdesk);
+ E_CONFIG_VAL(_G.config_edd, Config, tile_dialogs, INT);
+ E_CONFIG_VAL(_G.config_edd, Config, show_titles, INT);
+ E_CONFIG_VAL(_G.config_edd, Config, keyhints, STR);
+
+ E_CONFIG_LIST(_G.config_edd, Config, vdesks, _G.vdesk_edd);
+ E_CONFIG_VAL(_G.vdesk_edd, struct _Config_vdesk, x, INT);
+ E_CONFIG_VAL(_G.vdesk_edd, struct _Config_vdesk, y, INT);
+ E_CONFIG_VAL(_G.vdesk_edd, struct _Config_vdesk, zone_num, INT);
+ E_CONFIG_VAL(_G.vdesk_edd, struct _Config_vdesk, nb_stacks, INT);
+ E_CONFIG_VAL(_G.vdesk_edd, struct _Config_vdesk, use_rows, INT);
+
+ tiling_g.config = e_config_domain_load("module.tiling", _G.config_edd);
+ if (!tiling_g.config) {
+ tiling_g.config = E_NEW(Config, 1);
+ tiling_g.config->tile_dialogs = 1;
+ tiling_g.config->show_titles = 1;
+ }
+ if (!tiling_g.config->keyhints)
+ tiling_g.config->keyhints = strdup(tiling_g.default_keyhints);
+ else
+ tiling_g.config->keyhints = strdup(tiling_g.config->keyhints);
+
+ E_CONFIG_LIMIT(tiling_g.config->tile_dialogs, 0, 1);
+ E_CONFIG_LIMIT(tiling_g.config->show_titles, 0, 1);
+
+ for (Eina_List *l = tiling_g.config->vdesks; l; l = l->next) {
+ struct _Config_vdesk *vd;
+
+ vd = l->data;
+
+ E_CONFIG_LIMIT(vd->nb_stacks, 0, TILING_MAX_STACKS);
+ E_CONFIG_LIMIT(vd->use_rows, 0, 1);
+ }
+
+ desk = get_current_desk();
+ _G.tinfo = _initialize_tinfo(desk);
+
+ _G.input_mode = INPUT_MODE_NONE;
+ _G.currently_switching_desktop = 0;
+ _G.action_cb = NULL;
+
+ return m;
+}
+
+EAPI int
+e_modapi_shutdown(E_Module *m)
+{
+
+ if (tiling_g.log_domain >= 0) {
+ eina_log_domain_unregister(tiling_g.log_domain);
+ tiling_g.log_domain = -1;
+ }
+
+ if (_G.pre_border_assign_hook) {
+ e_border_hook_del(_G.pre_border_assign_hook);
+ _G.pre_border_assign_hook = NULL;
+ }
+
+#define FREE_HANDLER(x) \
+ if (x) { \
+ ecore_event_handler_del(x); \
+ x = NULL; \
+ }
+ FREE_HANDLER(_G.handler_border_resize);
+ FREE_HANDLER(_G.handler_border_move);
+ FREE_HANDLER(_G.handler_border_add);
+ FREE_HANDLER(_G.handler_border_remove);
+
+ FREE_HANDLER(_G.handler_border_iconify);
+ FREE_HANDLER(_G.handler_border_uniconify);
+ FREE_HANDLER(_G.handler_border_stick);
+ FREE_HANDLER(_G.handler_border_unstick);
+
+ FREE_HANDLER(_G.handler_desk_show);
+ FREE_HANDLER(_G.handler_desk_before_show);
+ FREE_HANDLER(_G.handler_desk_set);
+#undef FREE_HANDLER
+
+
+#define ACTION_DEL(act, title, value) \
+ if (act) { \
+ e_action_predef_name_del(_("Tiling"), _(title)); \
+ e_action_del(value); \
+ act = NULL; \
+ }
+ ACTION_DEL(_G.act_togglefloat, "Toggle floating", "toggle_floating");
+ ACTION_DEL(_G.act_addstack, "Add a stack", "add_stack");
+ ACTION_DEL(_G.act_removestack, "Remove a stack", "remove_stack");
+ ACTION_DEL(_G.act_tg_stack, "Toggle between rows and columns", "tg_cols_rows");
+ ACTION_DEL(_G.act_swap, "Swap a window with an other", "swap");
+ ACTION_DEL(_G.act_move, "Move window", "move");
+ ACTION_DEL(_G.act_adjusttransitions, "Adjust transitions",
+ "adjust_transitions");
+ ACTION_DEL(_G.act_go, "Focus a particular window", "go");
+#undef ACTION_DEL
+
+ e_configure_registry_item_del("windows/tiling");
+ e_configure_registry_category_del("windows");
+
+ end_special_input();
+
+ free(tiling_g.config->keyhints);
+ E_FREE(tiling_g.config);
+ E_CONFIG_DD_FREE(_G.config_edd);
+ E_CONFIG_DD_FREE(_G.vdesk_edd);
+
+ tiling_g.module = NULL;
+
+ eina_hash_free(_G.info_hash);
+ _G.info_hash = NULL;
+
+ eina_hash_free(_G.border_extras);
+ _G.border_extras = NULL;
+
+ _G.tinfo = NULL;
+
+ return 1;
+}
+
+EAPI int
+e_modapi_save(E_Module *m)
+{
+ e_config_domain_save("module.tiling", _G.config_edd, tiling_g.config);
+
+ return EINA_TRUE;
+}
+/* }}} */