Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37485643
en ru br
Репозитории ALT

Группа :: Графические оболочки/GNOME
Пакет: notify-osd

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: notify-osd-leolik.patch
Скачать


Index: src/bubble.c
===================================================================
--- src/bubble.c.orig
+++ src/bubble.c
@@ -128,25 +128,25 @@ enum
 // FIXME: this is in class Defaults already, but not yet hooked up so for the
 // moment we use the macros here, these values reflect the visual-guideline
 // for jaunty notifications
-#define TEXT_TITLE_COLOR_R 1.0f
-#define TEXT_TITLE_COLOR_G 1.0f
-#define TEXT_TITLE_COLOR_B 1.0f
-#define TEXT_TITLE_COLOR_A 1.0f
-
-#define TEXT_BODY_COLOR_R  0.91f
-#define TEXT_BODY_COLOR_G  0.91f
-#define TEXT_BODY_COLOR_B  0.91f
-#define TEXT_BODY_COLOR_A  1.0f
+float TEXT_TITLE_COLOR_R = 1.0f;
+float TEXT_TITLE_COLOR_G = 1.0f;
+float TEXT_TITLE_COLOR_B = 1.0f;
+float TEXT_TITLE_COLOR_A = 1.0f;
+
+float TEXT_BODY_COLOR_R  = 0.91f;
+float TEXT_BODY_COLOR_G  = 0.91f;
+float TEXT_BODY_COLOR_B  = 0.91f;
+float TEXT_BODY_COLOR_A  = 1.0f;
 
 #define TEXT_SHADOW_COLOR_R 0.0f
 #define TEXT_SHADOW_COLOR_G 0.0f 
 #define TEXT_SHADOW_COLOR_B 0.0f 
-#define TEXT_SHADOW_COLOR_A 1.0f 
+float TEXT_SHADOW_COLOR_A  = 1.0f;
 
-#define BUBBLE_BG_COLOR_R  0.15f
-#define BUBBLE_BG_COLOR_G  0.15f
-#define BUBBLE_BG_COLOR_B  0.15f
-#define BUBBLE_BG_COLOR_A  0.9f
+float BUBBLE_BG_COLOR_R  = 0.07f;
+float BUBBLE_BG_COLOR_G  = 0.07f;
+float BUBBLE_BG_COLOR_B  = 0.07f;
+float BUBBLE_BG_COLOR_A  = 0.9f;
 
 #define INDICATOR_UNLIT_R  1.0f
 #define INDICATOR_UNLIT_G  1.0f
@@ -3377,6 +3377,8 @@ bubble_recalc_size (Bubble *self)
 	gint           old_bubble_height = 0;
 	gint           new_bubble_width  = 0;
 	gint           new_bubble_height = 0;
+	gint		   x;
+ 	gint		   y;
 	Defaults*      d;
 	BubblePrivate* priv;
 
@@ -3571,6 +3573,13 @@ bubble_recalc_size (Bubble *self)
 		_refresh_body (self);
 
 	update_shape (self);
+	
+	if (defaults_get_gravity (d) == GRAVITY_SOUTH_EAST)
+ 	{
+ 		bubble_get_position(self, &x, &y);
+ 		bubble_move(self, x, y - (new_bubble_height - old_bubble_height));
+ 	}
+ 	
 }
 
 void
Index: src/defaults.c
===================================================================
--- src/defaults.c.orig
+++ src/defaults.c
@@ -114,40 +114,41 @@ enum
 /* these values are interpreted as em-measurements and do comply to the 
  * visual guide for jaunty-notifications */
 #define DEFAULT_DESKTOP_BOTTOM_GAP    6.0f
-#define DEFAULT_BUBBLE_WIDTH         24.0f
-#define DEFAULT_BUBBLE_MIN_HEIGHT     5.0f
-#define DEFAULT_BUBBLE_MAX_HEIGHT    12.2f
-#define DEFAULT_BUBBLE_VERT_GAP       0.5f
-#define DEFAULT_BUBBLE_HORZ_GAP       0.5f
+float DEFAULT_BUBBLE_WIDTH  = 24.0f;
+float DEFAULT_BUBBLE_MIN_HEIGHT  = 5.0f;
+float DEFAULT_BUBBLE_MAX_HEIGHT  = 12.2f;
+float DEFAULT_BUBBLE_VERT_GAP  = 0.5f;
+float DEFAULT_BUBBLE_HORZ_GAP  = 0.5f;
 #define DEFAULT_BUBBLE_SHADOW_SIZE    0.7f
 #define DEFAULT_BUBBLE_SHADOW_COLOR  "#000000"
 #define DEFAULT_BUBBLE_BG_COLOR      "#131313"
 #define DEFAULT_BUBBLE_BG_OPACITY    "#cc"
 #define DEFAULT_BUBBLE_HOVER_OPACITY "#66"
-#define DEFAULT_BUBBLE_CORNER_RADIUS 0.375f
+float DEFAULT_BUBBLE_CORNER_RADIUS  = 0.375f;
 #define DEFAULT_CONTENT_SHADOW_SIZE  0.125f
 #define DEFAULT_CONTENT_SHADOW_COLOR "#000000"
-#define DEFAULT_MARGIN_SIZE          1.0f
-#define DEFAULT_ICON_SIZE            3.0f
-#define DEFAULT_GAUGE_SIZE           0.625f
-#define DEFAULT_GAUGE_OUTLINE_WIDTH  0.125f
+float DEFAULT_MARGIN_SIZE  = 1.0f;
+float DEFAULT_ICON_SIZE  = 3.0f;
+float DEFAULT_GAUGE_SIZE  = 0.625f;
+#define DEFAULT_GAUGE_OUTLINE_WIDTH	 0.125f
 #define DEFAULT_TEXT_FONT_FACE       "Sans"
 #define DEFAULT_TEXT_TITLE_COLOR     "#ffffff"
-#define DEFAULT_TEXT_TITLE_WEIGHT    TEXT_WEIGHT_BOLD
-#define DEFAULT_TEXT_TITLE_SIZE      1.0f
+short DEFAULT_TEXT_TITLE_WEIGHT  = TEXT_WEIGHT_BOLD;
+float DEFAULT_TEXT_TITLE_SIZE  = 1.0f;
 #define DEFAULT_TEXT_BODY_COLOR      "#eaeaea"
-#define DEFAULT_TEXT_BODY_WEIGHT     TEXT_WEIGHT_NORMAL
-#define DEFAULT_TEXT_BODY_SIZE       0.9f
+short DEFAULT_TEXT_BODY_WEIGHT  = TEXT_WEIGHT_NORMAL;
+float DEFAULT_TEXT_BODY_SIZE  = 0.9f;
 #define DEFAULT_PIXELS_PER_EM        10.0f
 #define DEFAULT_SYSTEM_FONT_SIZE     10.0f
 #define DEFAULT_SCREEN_DPI           96.0f
 #define DEFAULT_GRAVITY              GRAVITY_NORTH_EAST
+short SLOT_ALLOCATION  = SLOT_ALLOCATION_DYNAMIC;
 
 /* these values are interpreted as milliseconds-measurements and do comply to
  * the visual guide for jaunty-notifications */
-#define DEFAULT_FADE_IN_TIMEOUT      250
-#define DEFAULT_FADE_OUT_TIMEOUT     1000
-#define DEFAULT_ON_SCREEN_TIMEOUT    10000
+float DEFAULT_FADE_IN_TIMEOUT  = 250;
+float DEFAULT_FADE_OUT_TIMEOUT  = 1000;
+float DEFAULT_ON_SCREEN_TIMEOUT  = 10000;
 
 /* notify-osd settings */
 #define NOTIFY_OSD_SCHEMA            "com.canonical.notify-osd"
@@ -280,7 +281,7 @@ _get_gravity (Defaults* self)
 	gravity = g_settings_get_int (self->nosd_settings, GSETTINGS_GRAVITY_KEY);
 
 	// protect against out-of-bounds values for gravity
-	if (gravity != GRAVITY_EAST && gravity != GRAVITY_NORTH_EAST)
+	if (gravity != GRAVITY_EAST && gravity != GRAVITY_NORTH_EAST && gravity != GRAVITY_WEST && gravity != GRAVITY_NORTH_WEST && gravity != GRAVITY_SOUTH_EAST && gravity != GRAVITY_SOUTH_WEST)
 		gravity = DEFAULT_GRAVITY;
 
 	// update stored DPI-value
@@ -764,7 +765,7 @@ defaults_init (Defaults* self)
 					  self);
 
 	// use fixed slot-allocation for async. and sync. bubbles
-	self->slot_allocation = SLOT_ALLOCATION_FIXED;
+	self->slot_allocation = SLOT_ALLOCATION;
 }
 
 static void
@@ -1764,7 +1765,7 @@ defaults_class_init (DefaultsClass* klas
 				"gravity",
 				"Positional hint for placing bubbles",
 				0,
-				2,
+				6,
 				DEFAULT_GRAVITY,
 				G_PARAM_CONSTRUCT |
 				G_PARAM_READWRITE |
Index: src/defaults.h
===================================================================
--- src/defaults.h.orig
+++ src/defaults.h
@@ -58,7 +58,13 @@ typedef enum
 {
         GRAVITY_NONE = 0,
         GRAVITY_NORTH_EAST, // top-right of screen
-        GRAVITY_EAST        // vertically centered at right of screen
+        GRAVITY_EAST,       // vertically centered at right of screen
+        GRAVITY_SOUTH_EAST,  // bottom-left of screen
+        GRAVITY_SOUTH_WEST,  // bottom-right of screen
+        GRAVITY_WEST,  // vertically centered at left of screen
+        GRAVITY_NORTH_WEST		// top-left of screen
+        
+        
 } Gravity;
 
 typedef enum
Index: src/display.c
===================================================================
--- src/display.c.orig
+++ src/display.c
@@ -310,8 +310,10 @@ stack_layout (Stack* self)
 		return;
 	}
 
+    /*
 	bubble_set_timeout (bubble,
 			    defaults_get_on_screen_timeout (self->defaults));
+                */
 
 	defaults_get_top_corner (self->defaults, &x, &y);
 
Index: src/main.c
===================================================================
--- src/main.c.orig
+++ src/main.c
@@ -25,6 +25,10 @@
 ** with this program.  If not, see <http://www.gnu.org/licenses/>.
 **
 *******************************************************************************/
+#define _GNU_SOURCE    /* getline */
+#include <unistd.h>    /* getuid */
+#include <pwd.h>       /* getpwuid */
+#include <sys/types.h>
 
 #include <string.h>
 #include <stdlib.h>
@@ -39,6 +43,197 @@
 
 #define ICONS_DIR  (DATADIR G_DIR_SEPARATOR_S "notify-osd" G_DIR_SEPARATOR_S "icons")
 
+/* begin hack */
+extern float TEXT_TITLE_COLOR_R;
+extern float TEXT_TITLE_COLOR_G;
+extern float TEXT_TITLE_COLOR_B;
+extern float TEXT_TITLE_COLOR_A;
+
+extern float TEXT_BODY_COLOR_R;
+extern float TEXT_BODY_COLOR_G;
+extern float TEXT_BODY_COLOR_B;
+extern float TEXT_BODY_COLOR_A;
+
+extern float TEXT_SHADOW_COLOR_A;
+
+extern float BUBBLE_BG_COLOR_R;
+extern float BUBBLE_BG_COLOR_G;
+extern float BUBBLE_BG_COLOR_B;
+extern float BUBBLE_BG_COLOR_A;
+
+extern float DEFAULT_TEXT_TITLE_SIZE;
+extern float DEFAULT_TEXT_BODY_SIZE;
+extern float DEFAULT_ON_SCREEN_TIMEOUT;
+
+extern short DEFAULT_TEXT_TITLE_WEIGHT;
+extern short DEFAULT_TEXT_BODY_WEIGHT;
+extern short SLOT_ALLOCATION;
+
+extern float DEFAULT_MARGIN_SIZE;
+extern float DEFAULT_BUBBLE_CORNER_RADIUS;
+extern float DEFAULT_BUBBLE_WIDTH;
+extern float DEFAULT_BUBBLE_VERT_GAP;
+extern float DEFAULT_BUBBLE_HORZ_GAP;
+extern float DEFAULT_ICON_SIZE;
+extern float DEFAULT_GAUGE_SIZE;
+
+void parse_color(unsigned int c, float* r, float* g, float* b) 
+{
+    *b = (float)(c & 0xFF) / (float)(0xFF);
+    c >>= 8;
+    *g = (float)(c & 0xFF) / (float)(0xFF);
+    c >>= 8;
+    *r = (float)(c & 0xFF) / (float)(0xFF);
+}
+
+
+void load_settings(void)
+{
+    char file[PATH_MAX];
+    uid_t uid = getuid();
+    const char* settings_file_name = ".notify-osd";
+    
+    struct passwd* pw = getpwuid(uid);
+    if (!pw) {
+        fprintf(stderr,
+                "failed to retrieve home directory. using default settings.\n");
+        return;
+    }
+    /* $HOME/.notify-osd */
+    snprintf(file, sizeof(file), "%s%s%s", pw->pw_dir,
+             G_DIR_SEPARATOR_S, settings_file_name);
+
+    FILE* fp = fopen(file, "r");
+
+    if (!fp) {
+        fprintf(stderr, "could not open '%s'. using default settings.\n", file);
+        return;
+
+    }
+    printf("reading settings from '%s'\n", file);
+
+    char* buf = NULL;
+    size_t size = 0;
+    char key[32], value[32];
+    float fvalue;
+    unsigned int ivalue;
+ 
+    while(getline(&buf, &size, fp) != -1) {
+        if (sscanf(buf, "%31s = %31s", key, value) != 2)
+            continue;
+        if (!strcmp(key, "bubble-background-color") &&
+            sscanf(value, "%x", &ivalue)) {
+
+            parse_color(ivalue, &BUBBLE_BG_COLOR_R, &BUBBLE_BG_COLOR_G,
+                        &BUBBLE_BG_COLOR_B);
+            
+
+        } else if (!strcmp(key, "bubble-background-opacity") &&
+                   sscanf(value, "%f", &fvalue)) {
+            
+            BUBBLE_BG_COLOR_A = fvalue*0.01;
+            
+        } else if (!strcmp(key, "text-title-color")  &&
+                   sscanf(value, "%x", &ivalue) ) {
+
+            parse_color(ivalue, &TEXT_TITLE_COLOR_R, &TEXT_TITLE_COLOR_G,
+                        &TEXT_TITLE_COLOR_B);
+            
+        } else if (!strcmp(key, "text-title-opacity") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            
+            TEXT_TITLE_COLOR_A = fvalue*0.01;
+            
+        } else if (!strcmp(key, "text-body-color")  &&
+                   sscanf(value, "%x", &ivalue) ) {
+
+            parse_color(ivalue, &TEXT_BODY_COLOR_R, &TEXT_BODY_COLOR_G,
+                        &TEXT_BODY_COLOR_B);
+
+        } else if (!strcmp(key, "text-body-opacity") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            
+            TEXT_BODY_COLOR_A = fvalue*0.01;
+            
+        } else if (!strcmp(key, "text-shadow-opacity") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            
+            TEXT_SHADOW_COLOR_A = fvalue*0.01;
+            
+        } else if (!strcmp(key, "text-title-size") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_TEXT_TITLE_SIZE = fvalue*0.01;
+            
+        } else if (!strcmp(key, "text-body-size") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_TEXT_BODY_SIZE = fvalue*0.01;
+            
+        } else if (!strcmp(key, "bubble-expire-timeout") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_ON_SCREEN_TIMEOUT = fvalue*1000;
+            
+        } else if (!strcmp(key, "text-title-weight")) {
+					if (!strcmp(value, "bold")) {
+						DEFAULT_TEXT_TITLE_WEIGHT = 700;
+					} else	if (!strcmp(value, "normal")) {
+						DEFAULT_TEXT_TITLE_WEIGHT = 400;
+					} else	if (!strcmp(value, "light")) {
+						DEFAULT_TEXT_TITLE_WEIGHT = 300;
+					}
+        } else if (!strcmp(key, "text-body-weight")) {
+					if (!strcmp(value, "bold")) {
+						DEFAULT_TEXT_BODY_WEIGHT = 700;
+					} else	if (!strcmp(value, "normal")) {
+						DEFAULT_TEXT_BODY_WEIGHT = 400;
+					} else	if (!strcmp(value, "light")) {
+						DEFAULT_TEXT_BODY_WEIGHT = 300;
+					}
+        } else if (!strcmp(key, "text-margin-size") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_MARGIN_SIZE = fvalue*0.1;
+            
+        } else if (!strcmp(key, "bubble-corner-radius") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_BUBBLE_CORNER_RADIUS = fvalue*0.01;
+            
+        } else if (!strcmp(key, "bubble-width") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_BUBBLE_WIDTH = fvalue*0.1;
+            
+        } else if (!strcmp(key, "slot-allocation")) {
+					if (!strcmp(value, "dynamic")) {
+						SLOT_ALLOCATION = SLOT_ALLOCATION_DYNAMIC;
+					} else	if (!strcmp(value, "fixed")) {
+						SLOT_ALLOCATION = SLOT_ALLOCATION_FIXED;
+					}
+        } else if (!strcmp(key, "bubble-vertical-gap") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_BUBBLE_VERT_GAP = fvalue*0.1;
+            
+        } else if (!strcmp(key, "bubble-horizontal-gap") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_BUBBLE_HORZ_GAP = fvalue*0.1;
+            
+        } else if (!strcmp(key, "bubble-icon-size") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_ICON_SIZE = fvalue*0.1;
+            
+        } else if (!strcmp(key, "bubble-gauge-size") &&
+                   sscanf(value, "%f", &fvalue) ) {
+            DEFAULT_GAUGE_SIZE = fvalue*0.1;
+            
+        }
+        
+    }
+
+    if (buf) {
+        free(buf);
+    }
+
+    fclose(fp);
+}
+/* end hack */
+
 int
 main (int    argc,
       char** argv)
@@ -58,6 +253,8 @@ main (int    argc,
 	gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
 	                                  ICONS_DIR);
 
+	load_settings();
+	
 	defaults = defaults_new ();
 	observer = observer_new ();
 	stack = stack_new (defaults, observer);
Index: src/stack.c
===================================================================
--- src/stack.c.orig
+++ src/stack.c
@@ -44,6 +44,7 @@
 G_DEFINE_TYPE (Stack, stack, G_TYPE_OBJECT);
 
 #define FORCED_SHUTDOWN_THRESHOLD 500
+#define NOTIFY_EXPIRES_DEFAULT -1
 
 /* fwd declaration */
 void close_handler (GObject* n, Stack*  stack);
@@ -574,6 +575,8 @@ stack_notify_handler (Stack*
 {
 	Bubble*    bubble     = NULL;
 	Bubble*    app_bubble = NULL;
+	Bubble*	   bottom_bubble = NULL;
+ 	gint	   x, y, temp_x, temp_y;
 	GValue*    data       = NULL;
 	GValue*    compat     = NULL;
 	GdkPixbuf* pixbuf     = NULL;
@@ -650,6 +653,15 @@ stack_notify_handler (Stack*
 	if (body)
 		bubble_set_message_body (bubble, body);
 
+    if (timeout == NOTIFY_EXPIRES_DEFAULT) {
+        bubble_set_timeout (bubble,
+                            defaults_get_on_screen_timeout (self->defaults));
+    }
+    else {
+        bubble_set_timeout (bubble, timeout);
+    }
+			    
+
 	if (new_bubble && bubble_is_append_allowed(bubble)) {
 		app_bubble = find_bubble_for_append(self, bubble);
 
@@ -747,8 +759,26 @@ stack_notify_handler (Stack*
 			  "..." : icon);
 
 	bubble_determine_layout (bubble);
+	
+	if (defaults_get_gravity (self->defaults) == GRAVITY_SOUTH_EAST)
+ 		bubble_get_position(bubble, &temp_x, &temp_y); 
 
 	bubble_recalc_size (bubble);
+	
+	if (defaults_get_gravity (self->defaults) == GRAVITY_SOUTH_EAST)
+ 	{
+ 		bubble_get_position(bubble, &x, &y);
+ 		y = y - temp_y;
+ 
+ 		if (self->slots[SLOT_TOP] == bubble)
+ 		{
+ 			
+ 			bottom_bubble = self->slots[SLOT_BOTTOM];
+ 			bubble_get_position(bottom_bubble, &temp_x, &temp_y);
+ 			bubble_move(bottom_bubble, temp_x, temp_y + y);
+ 		}
+ 	}
+ 
 
 	if (bubble_is_synchronous (bubble))
 	{
@@ -948,8 +978,7 @@ stack_get_slot_position (Stack* self,
 					case SLOT_ALLOCATION_FIXED:
 						*y += EM2PIXELS (defaults_get_icon_size (d), d) +
 						      2 * EM2PIXELS (defaults_get_margin_size (d), d) +
-						      EM2PIXELS (defaults_get_bubble_vert_gap (d), d); /* +
-						      2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d);*/
+						      EM2PIXELS (defaults_get_bubble_vert_gap (d), d) + 2;
 					break;
 
 					case SLOT_ALLOCATION_DYNAMIC:
@@ -965,6 +994,161 @@ stack_get_slot_position (Stack* self,
 
 			}
 		break;
+		
+		case GRAVITY_WEST:
+			d = self->defaults;
+
+			*x = defaults_get_desktop_left (d);
+
+			// the position for the sync./feedback bubble
+			if (slot == SLOT_TOP)
+				*y += defaults_get_desktop_height (d) / 2 -
+				      EM2PIXELS (defaults_get_bubble_vert_gap (d) / 2.0f, d) -
+				      bubble_height +
+				      EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+			// the position for the async. bubble
+			else if (slot == SLOT_BOTTOM)
+				*y += defaults_get_desktop_height (d) / 2 +
+				      EM2PIXELS (defaults_get_bubble_vert_gap (d) / 2.0f, d) -
+				      EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+		break;
+
+		case GRAVITY_NORTH_WEST:
+			d = self->defaults;
+
+			*x = defaults_get_desktop_left (d);
+
+			if (slot == SLOT_BOTTOM)
+			{
+				switch (defaults_get_slot_allocation (d))
+				{
+					case SLOT_ALLOCATION_FIXED:
+						*y += EM2PIXELS (defaults_get_icon_size (d), d) +
+						      2 * EM2PIXELS (defaults_get_margin_size (d), d) +
+						      EM2PIXELS (defaults_get_bubble_vert_gap (d), d) + 2;
+					break;
+
+					case SLOT_ALLOCATION_DYNAMIC:
+						g_assert (stack_is_slot_vacant (self, SLOT_TOP) == OCCUPIED);
+						*y += bubble_get_height (self->slots[SLOT_TOP]) +
+						      EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+						      2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+					break;
+
+					default:
+					break;
+				}
+
+			}
+		break;
+		
+ 		case GRAVITY_SOUTH_EAST:
+ 			d = self->defaults;
+ 			
+			switch (defaults_get_slot_allocation (d))
+			{
+				case SLOT_ALLOCATION_FIXED:
+					if (slot == SLOT_TOP)
+					{
+						*y += defaults_get_desktop_height (d) -
+							  2 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+							  bubble_height +
+							  2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+							  
+					}
+		 
+					if (slot == SLOT_BOTTOM)
+					{
+						*y += defaults_get_desktop_height (d) -
+							  bubble_height -
+							  EM2PIXELS (defaults_get_icon_size (d), d) -
+						      2 * EM2PIXELS (defaults_get_margin_size (d), d) -
+						      3 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) +
+						      2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d) - 2;
+							  
+					}
+				break;
+
+				case SLOT_ALLOCATION_DYNAMIC:
+					if (slot == SLOT_TOP)
+					{
+						*y += defaults_get_desktop_height (d) -
+							  2 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+							  bubble_height +
+							  2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+					}
+		 
+					if (slot == SLOT_BOTTOM)
+					{
+						g_assert (stack_is_slot_vacant (self, SLOT_TOP) == OCCUPIED);
+						*y += defaults_get_desktop_height (d) -
+							  3 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+							  bubble_height +
+							  4 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d) -
+							  bubble_get_height (self->slots[SLOT_TOP]);
+					}
+				break;
+
+				default:
+				break;
+			}
+				
+		break;
+		
+ 		case GRAVITY_SOUTH_WEST:
+ 			d = self->defaults;
+ 			
+ 			*x = defaults_get_desktop_left (d);
+ 			
+			switch (defaults_get_slot_allocation (d))
+			{
+				case SLOT_ALLOCATION_FIXED:
+					if (slot == SLOT_TOP)
+					{
+						*y += defaults_get_desktop_height (d) -
+							  2 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+							  bubble_height +
+							  2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+							  
+					}
+		 
+					if (slot == SLOT_BOTTOM)
+					{
+						*y += defaults_get_desktop_height (d) -
+							  bubble_height -
+							  EM2PIXELS (defaults_get_icon_size (d), d) -
+						      2 * EM2PIXELS (defaults_get_margin_size (d), d) -
+						      3 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) +
+						      2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d) - 2;
+							  
+					}
+				break;
+
+				case SLOT_ALLOCATION_DYNAMIC:
+					if (slot == SLOT_TOP)
+					{
+						*y += defaults_get_desktop_height (d) -
+							  2 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+							  bubble_height +
+							  2 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d);
+					}
+		 
+					if (slot == SLOT_BOTTOM)
+					{
+						g_assert (stack_is_slot_vacant (self, SLOT_TOP) == OCCUPIED);
+						*y += defaults_get_desktop_height (d) -
+							  3 * EM2PIXELS (defaults_get_bubble_vert_gap (d), d) -
+							  bubble_height +
+							  4 * EM2PIXELS (defaults_get_bubble_shadow_size (d), d) -
+							  bubble_get_height (self->slots[SLOT_TOP]);
+					}
+				break;
+
+				default:
+				break;
+			}
+				
+		break;
 
 		default:
 			g_warning ("Unhandled placement!\n");
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin