focus line theme patch



Hi:

I attach a (large) patch for Gtk+ which addresses bugzilla bugs

Its primary purpose is to allow focus to be drawn with thicker lines. 
However it also allows theme selection of the focus pattern as well as
the focus line thickness, and it also patches some widgets to use
gtk_style_draw_focus that previously did not (such as GtkCalendar).  It
makes gtkcolorsel respect these themed line attributes even though it
can't use draw_focus for the curved focus lines it draws.

The patch also cleans up a few problems with exterior focus for some
widgets (GtkEntry), etc.

Lastly, but importantly, it no longer uses hard-coded black for focus
lines (since that makes them invisible against really dar backgrounds)
but instead uses fg graphics contexts for the appropriate state.  This
also means that for widgets like toggle buttons that can be focussed in
more than one state, the focus line is always visible (assuming fg and
bg for that state are distinguishable from one another).

The reason the patch is big is that there are lots of places in Gtk+
where single-pixel-wide focus is assumed that needed to be fixed, and
also with wider focus lines some changes to widget requisitions should
be made for presentation reasons and to avoid overwriting labels, etc,
with the focus lines.  I have tested the patch with exterior and
interior focus, with line thicknesses of up to 10 pixels.  However I
plan to do another check if the patch is approved, since GTK drawing
code has changed substantially since I last tested the patch thoroughly.

regards,

Bill


regards,

Bill
? gtk/gtkentry.c.save
? gtk/gtkmarshalers.h
? gtk/stamp-gtkmarshalers.h
? gtk/gtkmarshalers.c
Index: gtk/gtkbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbutton.c,v
retrieving revision 1.76
diff -u -r1.76 gtkbutton.c
--- gtk/gtkbutton.c	2001/11/17 23:28:49	1.76
+++ gtk/gtkbutton.c	2001/11/18 05:34:45
@@ -37,8 +37,6 @@
 #include "gtkiconfactory.h"
 #include "gtkintl.h"
 
-#define CHILD_SPACING     1
-
 static GtkBorder default_default_border = { 1, 1, 1, 1 };
 static GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
 
@@ -697,9 +695,13 @@
   GtkButton *button = GTK_BUTTON (widget);
   GtkBorder default_border;
   gboolean interior_focus;
+  gint focus_width;
+  gint focus_pad;
 
   gtk_button_get_props (button, &default_border, NULL, &interior_focus);
-  
+  gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width,
+			"focus-padding", &focus_pad, NULL);
+ 
   requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
 			GTK_WIDGET (widget)->style->xthickness) * 2;
   requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
@@ -720,11 +722,10 @@
       requisition->width += child_requisition.width;
       requisition->height += child_requisition.height;
     }
-
-  if (interior_focus)
+  if (interior_focus) 
     {
-      requisition->width += 2;
-      requisition->height += 2;
+      requisition->width += 2*(focus_width+focus_pad);
+      requisition->height += 2*(focus_width+focus_pad);
     }
 }
 
@@ -741,7 +742,7 @@
   GtkBorder default_border;
 
   gtk_button_get_props (button, &default_border, NULL, NULL);
-  
+			    
   widget->allocation = *allocation;
 
   if (GTK_WIDGET_REALIZED (widget))
@@ -824,6 +825,8 @@
   GtkBorder default_border;
   GtkBorder default_outside_border;
   gboolean interior_focus;
+  gint focus_width;
+  gint focus_pad;
    
   if (GTK_WIDGET_DRAWABLE (widget))
     {
@@ -831,12 +834,17 @@
       button = GTK_BUTTON (widget);
 
       gtk_button_get_props (button, &default_border, &default_outside_border, &interior_focus);
+      gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width,
+			    "focus-padding", &focus_pad, NULL); 
 	
       x = widget->allocation.x + border_width;
       y = widget->allocation.y + border_width;
       width = widget->allocation.width - border_width * 2;
       height = widget->allocation.height - border_width * 2;
 
+      gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
+      gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
+
       if (GTK_WIDGET_HAS_DEFAULT (widget) &&
 	  GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL)
 	{
@@ -860,10 +868,10 @@
        
       if (!interior_focus && GTK_WIDGET_HAS_FOCUS (widget))
 	{
-	  x += 1;
-	  y += 1;
-	  width -= 2;
-	  height -= 2;
+	  x += focus_width + focus_pad;
+	  y += focus_width + focus_pad;
+	  width -= 2 * (focus_width + focus_pad);
+	  height -= 2 * (focus_width + focus_pad);
 	}
 
       shadow_type = button->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
@@ -880,22 +888,23 @@
 	{
 	  if (interior_focus)
 	    {
-	      x += widget->style->xthickness + 1;
-	      y += widget->style->ythickness + 1;
-	      width -= 2 * (widget->style->xthickness + 1);
-	      height -=  2 * (widget->style->xthickness + 1);
+	      x += widget->style->xthickness + focus_width/2 + focus_pad;
+	      y += widget->style->ythickness + focus_width/2 + focus_pad;
+	      width -= 2 * (widget->style->xthickness) + focus_width + 2 * focus_pad;
+	      height -=  2 * (widget->style->xthickness) + focus_width + 2 * focus_pad;
 	    }
 	  else
 	    {
-	      x -= 1;
-	      y -= 1;
-	      width += 2;
-	      height += 2;
+	      int focus_halfwidth = (focus_width + 1)/2;
+	      x -= focus_halfwidth + focus_pad;
+	      y -= focus_halfwidth + focus_pad;
+	      width += focus_width + focus_pad*2;
+	      height += focus_width + focus_pad*2;
 	    }
 
-	  gtk_paint_focus (widget->style, widget->window,
-			   area, widget, "button",
-			   x, y, width - 1, height - 1);
+	  gtk_paint_focus (widget->style, widget->window, area, widget,
+			   GTK_WIDGET_STATE (widget), "button",
+			   x, y, width, height);
 	}
     }
 }
Index: gtk/gtkbutton.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbutton.h,v
retrieving revision 1.21
diff -u -r1.21 gtkbutton.h
--- gtk/gtkbutton.h	2001/11/15 21:04:47	1.21
+++ gtk/gtkbutton.h	2001/11/18 05:34:45
@@ -48,6 +48,9 @@
 typedef struct _GtkButton       GtkButton;
 typedef struct _GtkButtonClass  GtkButtonClass;
 
+#define CHILD_SPACING     1
+#define DEFAULT_FOCUS_PAD 1
+
 struct _GtkButton
 {
   GtkBin bin;
Index: gtk/gtkcalendar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcalendar.c,v
retrieving revision 1.37
diff -u -r1.37 gtkcalendar.c
--- gtk/gtkcalendar.c	2001/09/20 19:35:08	1.37
+++ gtk/gtkcalendar.c	2001/11/18 05:34:49
@@ -1155,9 +1155,11 @@
   gint calendar_margin = CALENDAR_MARGIN;
   gint header_width, main_width;
   gint max_header_height = 0;
+  gint focus_width;
   
   calendar = GTK_CALENDAR (widget);
   private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
+  gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width, NULL);
 
   layout = gtk_widget_create_pango_layout (widget, NULL);
   
@@ -1207,12 +1209,13 @@
   /* Mainwindow labels width */
   
   private_data->max_day_char_width = 0;
+  private_data->min_day_width = 0;
   for (i = 0; i < 9; i++)
     {
       sprintf (buffer, "%d%d", i, i);
       pango_layout_set_text (layout, buffer, -1);	  
       pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-      private_data->min_day_width = MAX (private_data->max_day_char_width,
+      private_data->min_day_width = MAX (private_data->min_day_width,
 					 logical_rect.width);
 
       private_data->max_day_char_ascent = MAX (private_data->max_label_char_ascent,
@@ -1221,7 +1224,7 @@
 						PANGO_DESCENT (logical_rect));
     }
   /* We add one to max_day_char_width to be able to make the marked day "bold" */
-  private_data->max_day_char_width = private_data->min_day_width / 2 +1;
+  private_data->max_day_char_width = private_data->min_day_width / 2 + 1;
   
   if (calendar->display_flags & GTK_CALENDAR_SHOW_DAY_NAMES)
     for (i = 0; i < 7; i++)
@@ -1247,7 +1250,8 @@
 						 logical_rect.width / 2);
       }
   
-  main_width = (7 * (private_data->min_day_width + DAY_XPAD * 2) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2
+  main_width = (7 * (private_data->min_day_width + DAY_XPAD * 2 + focus_width - 1)
+		+ (DAY_XSEP * 6) + CALENDAR_MARGIN * 2
 		+ (private_data->max_week_char_width
 		   ? private_data->max_week_char_width * 2 + DAY_XPAD * 2 + CALENDAR_XSEP * 2
 		   : 0));
@@ -1261,7 +1265,7 @@
   
   if (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING)
     {
-      private_data->header_h = (max_header_height + CALENDAR_YSEP * 2);
+      private_data->header_h = (max_header_height + CALENDAR_YSEP * 2 + focus_width - 1);
     }
   else
     {
@@ -1272,7 +1276,7 @@
     {
       private_data->day_name_h = (private_data->max_label_char_ascent
 				  + private_data->max_label_char_descent
-				  + 2 * DAY_YPAD + calendar_margin);
+				  + 2 * DAY_YPAD + calendar_margin + 2 * focus_width);
       calendar_margin = CALENDAR_YSEP;
     } 
   else
@@ -1283,7 +1287,7 @@
   private_data->main_h = (CALENDAR_MARGIN + calendar_margin
 			  + 6 * (private_data->max_day_char_ascent
 				 + private_data->max_day_char_descent 
-				 + DAY_YPAD * 2)
+				 + DAY_YPAD * 2 + focus_width - 1)
 			  + DAY_YSEP * 5);
   
   /* 
@@ -1418,19 +1422,21 @@
   
   if (GTK_WIDGET_DRAWABLE (widget))
     {
+      gint focus_width;
+      gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
+      
       x = 0;
       y = 0;
       gdk_window_get_size (widget->window, &width, &height);
       gdk_window_clear (widget->window);
-      
-      gdk_draw_rectangle (widget->window, 
-			  widget->style->base_gc[GTK_WIDGET_STATE (widget)],
-			  FALSE, x + 2, y + 2, width - 5, height - 5);
-      
-      gtk_draw_shadow (widget->style, widget->window,
-		       GTK_STATE_NORMAL, GTK_SHADOW_IN,
-		       x, y, width, height);
-      
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+        {
+          gtk_paint_focus (widget->style, widget->window, NULL, widget,
+			   GTK_WIDGET_STATE (widget), "calendar",
+			   x + focus_width/2, y + focus_width/2,
+			   width - focus_width, height - focus_width);
+	}
     }
 }
 
@@ -1799,6 +1805,7 @@
   gint y_top;
   gint y_loc;
   gint day_xspace;
+  gint focus_width;
   GtkCalendarPrivateData *private_data;
   PangoLayout *layout;
   PangoRectangle logical_rect;
@@ -1809,6 +1816,8 @@
   calendar = GTK_CALENDAR (widget);
   private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
 
+  gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width, NULL);
+  
   /*
    * Handle freeze/thaw functionality
    */
@@ -1826,7 +1835,7 @@
   day = calendar->day[row][col];
   
   x_left = left_x_for_column (calendar, col);
-  x_loc = x_left + private_data->day_width / 2 + private_data->max_day_char_width;
+  x_loc = x_left + private_data->day_width / 2 + private_data->max_day_char_width + (focus_width - 1);
   
   y_top = top_y_for_row (calendar, row);
   
@@ -1889,9 +1898,18 @@
   if (GTK_WIDGET_HAS_FOCUS (calendar) 
       && calendar->focus_row == row && calendar->focus_col == col)
     {
-      gdk_draw_rectangle (private_data->main_win, calendar->xor_gc, 
-			  FALSE, x_left, y_top,
-			  private_data->day_width-1, day_height-1);
+	    gint focus_width;
+	    gtk_widget_style_get (GTK_WIDGET (calendar), "focus-line-width", &focus_width, NULL);
+	    gtk_paint_focus (GTK_WIDGET (calendar)->style,
+			     private_data->main_win,
+			     NULL,
+			     GTK_WIDGET (calendar),
+			     (calendar->selected_day == day) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL,
+			     "calendar-day", 
+			     x_left + focus_width/2,
+			     y_top + focus_width/2,
+			     private_data->day_width - focus_width,
+			     day_height - focus_width);
     }
 
   g_object_unref (G_OBJECT (layout));
Index: gtk/gtkcheckbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcheckbutton.c,v
retrieving revision 1.36
diff -u -r1.36 gtkcheckbutton.c
--- gtk/gtkcheckbutton.c	2001/11/15 21:04:47	1.36
+++ gtk/gtkcheckbutton.c	2001/11/18 05:34:50
@@ -159,8 +159,12 @@
     {
       gint border_width;
       gint interior_focus;
+      gint focus_width;
+      gint focus_pad;
 	  
-      gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL);
+      gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			    "focus-line-width", &focus_width,
+			    "focus-padding", &focus_pad, NULL);
 
       gtk_check_button_draw_indicator (check_button, area);
       
@@ -170,22 +174,25 @@
 	  if (interior_focus)
 	    {
 	      GtkWidget *child = GTK_BIN (widget)->child;
-
+	      gint focus_halfwidth = (focus_width + 1)/2;
+	      
 	      if (child && GTK_WIDGET_VISIBLE (child))
 		gtk_paint_focus (widget->style, widget->window,
-				 NULL, widget, "checkbutton",
-				 child->allocation.x - 1,
-				 child->allocation.y - 1,
-				 child->allocation.width + 1,
-				 child->allocation.height + 1);
+				 NULL, widget, GTK_WIDGET_STATE (widget),
+				 "checkbutton",
+				 child->allocation.x - focus_halfwidth - focus_pad,
+				 child->allocation.y - focus_halfwidth - focus_pad,
+				 child->allocation.width + focus_width + focus_pad,
+				 child->allocation.height + focus_width + focus_pad);
 	    }
 	  else
 	    gtk_paint_focus (widget->style, widget->window,
-			     NULL, widget, "checkbutton",
-			     border_width + widget->allocation.x,
-			     border_width + widget->allocation.y,
-			     widget->allocation.width - 2 * border_width - 1,
-			     widget->allocation.height - 2 * border_width - 1);
+			     NULL, widget,
+			     GTK_WIDGET_STATE (widget), "checkbutton",
+			     border_width + widget->allocation.x + focus_width/2 + focus_pad,
+			     border_width + widget->allocation.y + focus_width/2 + focus_pad,
+			     widget->allocation.width - 2 * border_width - focus_width - 2*focus_pad,
+			     widget->allocation.height - 2 * border_width - focus_width - 2*focus_pad);
 	}
     }
 }
@@ -222,9 +229,14 @@
       gint indicator_size;
       gint indicator_spacing;
       gint border_width = GTK_CONTAINER (widget)->border_width;
-      
-      requisition->width = border_width * 2 + 2;
-      requisition->height = border_width * 2 + 2;
+      gint focus_width;
+      gint focus_pad;
+
+      gtk_widget_style_get (GTK_WIDGET (widget), "focus-line-width", &focus_width,
+			    "focus-padding", &focus_pad, NULL);
+ 
+      requisition->width = (border_width + CHILD_SPACING) * 2;
+      requisition->height = (border_width + CHILD_SPACING) * 2;
 
       child = GTK_BIN (widget)->child;
       if (child && GTK_WIDGET_VISIBLE (child))
@@ -240,10 +252,10 @@
       _gtk_check_button_get_props (GTK_CHECK_BUTTON (widget),
  				   &indicator_size, &indicator_spacing);
       
-      requisition->width += (indicator_size + indicator_spacing * 3 + 2);
+      requisition->width += (indicator_size + indicator_spacing * 3 + 2*(focus_width+focus_pad));
       
       temp = (indicator_size + indicator_spacing * 2);
-      requisition->height = MAX (requisition->height, temp) + 2;
+      requisition->height = MAX (requisition->height, temp) + 2*(focus_width+focus_pad);
     }
   else
     (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
@@ -257,6 +269,12 @@
   GtkToggleButton *toggle_button;
   GtkButton *button;
   GtkAllocation child_allocation;
+  gint focus_pad = DEFAULT_FOCUS_PAD;
+  gint focus_width;
+  gint interior_focus;
+
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			"focus-line-width", &focus_width, NULL);
   
   g_return_if_fail (GTK_IS_CHECK_BUTTON (widget));
   g_return_if_fail (allocation != NULL);
@@ -284,15 +302,16 @@
  
 	  child_allocation.width = MIN (GTK_BIN (button)->child->requisition.width,
 					allocation->width -
-					((border_width + 1) * 2 + indicator_size + indicator_spacing * 3));
+					((border_width + focus_width + focus_pad) * 2
+					 + indicator_size + indicator_spacing * 3));
+
 	  child_allocation.height = MIN (GTK_BIN (button)->child->requisition.height,
-					 allocation->height - (border_width + 1) * 2);
-	  child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 + 1 +
-				widget->allocation.x);
+					 allocation->height - (border_width + focus_width + focus_pad) * 2);
+	  child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 +
+				widget->allocation.x + focus_width + focus_pad);
 	  child_allocation.y = widget->allocation.y +
-			       (allocation->height - child_allocation.height) / 2;
+		  (allocation->height - child_allocation.height) / 2;
 
-	  
 	  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
 	    child_allocation.x = allocation->x + allocation->width
 	      - (child_allocation.x - allocation->x + child_allocation.width);
@@ -367,6 +386,9 @@
   gint x, y;
   gint indicator_size;
   gint indicator_spacing;
+  gint focus_width;
+  gint focus_pad;
+  gboolean interior_focus;
   GdkWindow *window;
   
   g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button));
@@ -377,7 +399,11 @@
   if (GTK_WIDGET_DRAWABLE (check_button))
     {
       window = widget->window;
-      
+
+      gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			    "focus-line-width", &focus_width, 
+			    "focus-padding", &focus_pad, NULL);
+
       _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
 						    
       state_type = GTK_WIDGET_STATE (widget);
@@ -404,6 +430,11 @@
       y = widget->allocation.y + (widget->allocation.height - indicator_size) / 2;
       width = indicator_size;
       height = indicator_size;
+
+      if (!interior_focus)
+        {
+          x += focus_width + focus_pad;      
+        }
 
       state_type = GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE ? GTK_STATE_NORMAL : GTK_WIDGET_STATE (widget);
       if (GTK_TOGGLE_BUTTON (widget)->inconsistent)
Index: gtk/gtkcolorsel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcolorsel.c,v
retrieving revision 1.81
diff -u -r1.81 gtkcolorsel.c
--- gtk/gtkcolorsel.c	2001/11/17 23:28:49	1.81
+++ gtk/gtkcolorsel.c	2001/11/18 05:34:53
@@ -155,18 +155,10 @@
 					         GValue                  *value,
 					         GParamSpec              *pspec);
 
-static gint     gtk_color_selection_get_palette_size    (GtkColorSelection *colorsel);
-static gboolean gtk_color_selection_get_palette_color   (GtkColorSelection *colorsel,
-                                                         gint               index,
-                                                         GdkColor          *color);
-static void     gtk_color_selection_set_palette_color   (GtkColorSelection *colorsel,
-                                                         gint               index,
-                                                         GdkColor          *color);
-static void     gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel,
-                                                         gint               index);
+static GdkGC   *get_focus_gc                            (GtkWidget         *drawing_area,
+							 gint              *focus_width);
 static void     default_change_palette_func             (const GdkColor    *colors,
 							 gint               n_colors);
-
 static gpointer parent_class = NULL;
 static guint color_selection_signals[LAST_SIGNAL] = { 0 };
 
@@ -626,7 +618,7 @@
 {
   if (drawing_area->window == NULL)
     return;
-  
+
   gdk_window_clear_area (drawing_area->window,
 			 area->x,
 			 area->y,
@@ -635,23 +627,40 @@
   
   if (GTK_WIDGET_HAS_FOCUS (drawing_area))
     {
-      GdkGC *gc;
-      gdouble color[4];
-      
-      palette_get_color (drawing_area, color);
-      
-      if (INTENSITY (color[0], color[1], color[2]) > 0.5)
-	gc = drawing_area->style->black_gc;
-      else
-	gc = drawing_area->style->white_gc;
-
+      gint focus_width = 1;
+      GdkGC *gc = get_focus_gc (drawing_area, &focus_width);
       gdk_draw_rectangle (drawing_area->window,
-			  gc, FALSE, 0, 0,
-			  drawing_area->allocation.width - 1,
-			  drawing_area->allocation.height - 1);
+			  gc, FALSE, focus_width/2, focus_width/2,
+			  drawing_area->allocation.width - focus_width,
+			  drawing_area->allocation.height - focus_width);
     }
 }
 
+static GdkGC *
+get_focus_gc (GtkWidget *drawing_area, gint *focus_width)
+{
+  GdkGC *gc = gdk_gc_new(gtk_widget_get_parent_window (drawing_area));
+  gdouble color[4];
+  gint8 *dash_list;
+  
+  gtk_widget_style_get (drawing_area,
+			"focus-line-width", focus_width,
+			"focus-line-pattern", (gchar *)&dash_list,
+			NULL);
+      
+  palette_get_color (drawing_area, color);
+      
+  if (INTENSITY (color[0], color[1], color[2]) > 0.5)
+    gdk_gc_copy (gc, drawing_area->style->black_gc);
+  else
+    gdk_gc_copy (gc, drawing_area->style->white_gc);
+
+  gdk_gc_set_line_attributes (gc, *focus_width, GDK_LINE_ON_OFF_DASH, 0, 0);
+
+  gdk_gc_set_dashes (gc, 0, dash_list, strlen (dash_list));
+
+  return gc;
+}
 
 static void
 palette_drag_begin (GtkWidget      *widget,
Index: gtk/gtkentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
retrieving revision 1.165
diff -u -r1.165 gtkentry.c
--- gtk/gtkentry.c	2001/11/17 23:28:49	1.165
+++ gtk/gtkentry.c	2001/11/18 05:34:56
@@ -23,7 +23,6 @@
  * files for a list of changes.  These files are distributed with
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
-
 #include <string.h>
 
 #include <pango/pango.h>
@@ -988,6 +987,8 @@
   GtkRequisition requisition;
   GdkWindowAttr attributes;
   gint attributes_mask;
+  gint focus_width;
+  gboolean interior_focus;
 
   g_return_if_fail (GTK_IS_ENTRY (widget));
 
@@ -995,6 +996,9 @@
   entry = GTK_ENTRY (widget);
   editable = GTK_EDITABLE (widget);
 
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			"focus-line-width", &focus_width, NULL);
+  
   gtk_widget_get_child_requisition (widget, &requisition);
   
   attributes.window_type = GDK_WINDOW_CHILD;
@@ -1030,6 +1034,11 @@
       attributes.x = 0;
       attributes.y = 0;
     }
+  if (!interior_focus)
+    {
+      attributes.x += focus_width;
+      attributes.y += focus_width;
+    }
   
   attributes.width = widget->allocation.width - attributes.x * 2;
   attributes.height = requisition.height - attributes.y * 2;
@@ -1097,11 +1106,16 @@
   PangoFontMetrics *metrics;
   gint xborder, yborder;
   PangoContext *context;
+  gboolean interior_focus;
+  gint focus_width;
   
   g_return_if_fail (GTK_IS_ENTRY (widget));
   g_return_if_fail (requisition != NULL);
 
   entry = GTK_ENTRY (widget);
+
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus, 
+			"focus-line-width", &focus_width, NULL);
   
   context = gtk_widget_get_pango_context (widget);
   metrics = pango_context_get_metrics (context,
@@ -1113,15 +1127,21 @@
 
   xborder = INNER_BORDER;
   yborder = INNER_BORDER;
-  
+
   if (entry->has_frame)
     {
       xborder += widget->style->xthickness;
       yborder += widget->style->ythickness;
     }
-  else
+  
+  if (!interior_focus)
+    {
+      /* add enough space to draw focus rect in widget->window */
+      xborder += focus_width;
+      yborder += focus_width;
+    }
+  else if (!entry->has_frame) /* add one for backwards compat */
     {
-      /* add 1 pixel to draw focus rect in widget->window */
       xborder += 1;
       yborder += 1;
     }
@@ -1145,9 +1165,9 @@
              gint     *yborder)
 {
   GtkWidget *widget;
-
-  widget = GTK_WIDGET (entry);
   
+  widget = GTK_WIDGET (entry);
+	  
   if (entry->has_frame)
     {
       if (xborder)
@@ -1157,11 +1177,10 @@
     }
   else
     {
-      /* 1 pixel for focus rect */
       if (xborder)
         *xborder = 1;
       if (yborder)
-        *yborder = 1;
+	*yborder = 1;
     }
 }
 
@@ -1175,12 +1194,22 @@
   gint xborder, yborder;
   GtkRequisition requisition;
   GtkWidget *widget;
+  gint focus_width;
+  gboolean interior_focus;
 
   widget = GTK_WIDGET (entry);
-  
+
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			"focus-line-width", &focus_width, NULL);
+
   gtk_widget_get_child_requisition (widget, &requisition);
 
   get_borders (entry, &xborder, &yborder);
+  if (!interior_focus)
+    {
+      xborder += focus_width - 1;
+      yborder += focus_width - 1;
+    } 
 
   if (x)
     *x = xborder;
@@ -1274,10 +1303,12 @@
   gint width, height;
   GtkEntry *entry;
   gboolean interior_focus;
+  gint focus_width;
   
   g_return_if_fail (GTK_IS_ENTRY (widget));
 
-  gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL);
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			"focus-line-width", &focus_width, NULL);
 
   entry = GTK_ENTRY (widget);
   
@@ -1289,12 +1320,14 @@
 
           gdk_window_get_size (widget->window, &width, &height);
 
-          if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
+          gdk_window_clear (widget->window);
+	  
+          if (!interior_focus)
             {
-              x += 1;
-              y += 1;
-              width -= 2;
-              height -= 2;
+              x += focus_width;
+              y += focus_width;
+              width -= 2 * focus_width;
+	      height -= 2 * focus_width;
             }
 
           gtk_paint_shadow (widget->style, widget->window,
@@ -1302,15 +1335,14 @@
                             NULL, widget, "entry",
                             x, y, width, height);
         }
-      else
-        gdk_window_clear (widget->window);
         
       if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
         {
           gdk_window_get_size (widget->window, &width, &height);
           gtk_paint_focus (widget->style, widget->window, 
-                           NULL, widget, "entry",
-                           0, 0, width - 1, height - 1);
+                           NULL, widget, GTK_WIDGET_STATE (widget), "entry",
+                           focus_width/2, focus_width/2,
+			   width - focus_width, height - focus_width);
         }
     }
 }
@@ -1326,10 +1358,17 @@
 
   entry = GTK_ENTRY (widget);
 
-  if (widget->window == event->window)
-    gtk_entry_draw_focus (widget);
-  else if (entry->text_area == event->window)
+  if (GTK_WIDGET_HAS_FOCUS(widget) || entry->has_frame)
     {
+      gtk_entry_draw_focus (widget);
+    }
+  else
+    {
+      gdk_window_clear (widget->window);
+    }
+
+  if (entry->text_area == event->window)
+    {
       gtk_entry_draw_text (GTK_ENTRY (widget));
 
       if ((entry->visible || entry->invisible_char != 0) &&
@@ -2616,6 +2655,7 @@
     {
       PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
       gint area_width, area_height;
+      gint area_x, area_y;
       gint x, y;
       gint start_pos, end_pos;
       
@@ -2623,12 +2663,12 @@
       
       get_layout_position (entry, &x, &y);
 
-      get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
+      get_text_area_size (entry, &area_x, &area_y, &area_width, &area_height);
 
       gtk_paint_flat_box (widget->style, entry->text_area, 
 			  GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
 			  NULL, widget, "entry_bg", 
-			  0, 0, area_width, area_height);
+			  area_x, area_y, area_width, area_height);
 
       gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],       
                        x, y,
@@ -2750,8 +2790,8 @@
 
       cursor_location.x = xoffset + x1;
       cursor_location.y = INNER_BORDER;
-      cursor_location.width = 0;
       cursor_location.height = text_area_height - 2 * INNER_BORDER ;
+      cursor_location.width = 0;
       
       _gtk_draw_insertion_cursor (entry->text_area, gc1,
 				  &cursor_location, dir1);
Index: gtk/gtkhsv.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkhsv.c,v
retrieving revision 1.16
diff -u -r1.16 gtkhsv.c
--- gtk/gtkhsv.c	2001/11/17 23:28:50	1.16
+++ gtk/gtkhsv.c	2001/11/18 05:34:57
@@ -110,6 +110,10 @@
 static void gtk_hsv_move           (GtkHSV          *hsv,
                                     GtkDirectionType dir);
 
+static GdkGC *gtk_hsv_get_focus_gc (GtkHSV *hsv,
+				    gint *line_width);
+
+
 static guint hsv_signals[LAST_SIGNAL];
 static GtkWidgetClass *parent_class;
 
@@ -1040,15 +1044,19 @@
   if (GTK_WIDGET_HAS_FOCUS (hsv) &&
       priv->focus_on_ring)
     {
-      gdk_rgb_gc_set_foreground (priv->gc, 0x000000);
-      
-      gdk_draw_arc (drawable, priv->gc, FALSE,
-                    -x, -y,
-                    priv->size - 1, priv->size - 1,
+      gint focus_width = 1;
+      gint focus_halfwidth;
+      GdkGC *gc = gtk_hsv_get_focus_gc (hsv, &focus_width);
+      focus_halfwidth = MAX (focus_width/2, (focus_width+1)/2);
+      
+      gdk_draw_arc (drawable, gc, FALSE,
+                    -x + focus_width/2, -y + focus_width/2,
+                    priv->size - focus_width, priv->size - focus_width,
                     0, 360 * 64);
-      gdk_draw_arc (drawable, priv->gc, FALSE,
-                    -x + priv->ring_width - 1, -y + priv->ring_width - 1,
-                    priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1,
+      gdk_draw_arc (drawable, gc, FALSE,
+                    -x + priv->ring_width - focus_halfwidth, -y + priv->ring_width - focus_halfwidth,
+                    priv->size - 2 * priv->ring_width + focus_width,
+		    priv->size - 2 * priv->ring_width + focus_width,
                     0, 360 * 64);
     }
 }
@@ -1253,9 +1261,10 @@
   if (GTK_WIDGET_HAS_FOCUS (hsv) &&
       !priv->focus_on_ring)
     {
-      gdk_rgb_gc_set_foreground (priv->gc, 0x000000);
+      gint focus_width = 1;	    
+      GdkGC *gc = gtk_hsv_get_focus_gc (hsv, &focus_width);
   
-      gdk_draw_polygon (drawable, priv->gc, FALSE, points, 3);
+      gdk_draw_polygon (drawable, gc, FALSE, points, 3);
     }
   
   /* Draw value marker */
@@ -1723,3 +1732,33 @@
   gtk_hsv_set_color (hsv, hue, sat, val);
 }
 
+static GdkGC *
+gtk_hsv_get_focus_gc (GtkHSV *hsv, gint *line_width)
+{
+  static GdkGC *focus_gc = NULL;
+
+  if (!focus_gc)
+    {
+      GtkWidget *widget = GTK_WIDGET (hsv);
+      GtkStyle *style = widget->style;
+      gdouble color[4];
+      gint8 *dash_list;
+      char *dash;
+      gint dash_list_len = 0;
+
+      focus_gc = gdk_gc_new (gtk_widget_get_parent_window (widget));
+      gdk_gc_copy (focus_gc, style->fg_gc[GTK_STATE_NORMAL]);
+      gtk_widget_style_get (widget,
+			    "focus-line-width", line_width,
+			    "focus-line-pattern", (gchar *)&dash_list,
+			    NULL);
+
+      gdk_gc_set_line_attributes (focus_gc, *line_width, GDK_LINE_ON_OFF_DASH, 0, 0);
+
+      for (dash=(char*)dash_list, dash_list_len=0; *dash; ++dash, ++dash_list_len) ;
+      gdk_gc_set_dashes (focus_gc, 0, dash_list, dash_list_len);
+    }
+
+  return focus_gc;
+  
+}
Index: gtk/gtklabel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.c,v
retrieving revision 1.111
diff -u -r1.111 gtklabel.c
--- gtk/gtklabel.c	2001/11/17 23:28:50	1.111
+++ gtk/gtklabel.c	2001/11/18 05:35:00
@@ -1361,15 +1361,16 @@
       pango_layout_set_alignment (label->layout, align);
 
       if (label->wrap)
-	{
-	  GtkWidgetAuxInfo *aux_info;
-	  gint longest_paragraph;
-	  gint width, height;
-	  
-	  aux_info = _gtk_widget_get_aux_info (widget, FALSE);
-	  if (aux_info && aux_info->width > 0)
+        {
+          GtkWidgetAuxInfo *aux_info;
+          gint longest_paragraph;
+          gint width, height;
+          gint real_width;
+
+          aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+          if (aux_info && aux_info->width > 0)
 	    pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE);
-	  else
+          else
 	    {
 	      pango_layout_set_width (label->layout, -1);
 	      pango_layout_get_extents (label->layout, NULL, &logical_rect);
@@ -1384,7 +1385,7 @@
 							   "This long string gives a good enough length for any line to have."));
 	      width = MIN (width,
 			   PANGO_SCALE * (gdk_screen_width () + 1) / 2);
-	      
+	    
 	      pango_layout_set_width (label->layout, width);
 	      pango_layout_get_extents (label->layout, NULL, &logical_rect);
 	      height = logical_rect.height;
@@ -1395,7 +1396,7 @@
 	      if (longest_paragraph > 0)
 		{
 		  gint nlines, perfect_width;
-		  
+
 		  nlines = pango_layout_get_line_count (label->layout);
 		  perfect_width = (longest_paragraph + nlines - 1) / nlines;
 		  
@@ -1405,7 +1406,7 @@
 		      pango_layout_get_extents (label->layout, NULL, &logical_rect);
 		      
 		      if (logical_rect.height <= height)
-			width = perfect_width;
+		        width = perfect_width;
 		      else
 			{
 			  gint mid_width = (perfect_width + width) / 2;
@@ -1419,8 +1420,8 @@
 				width = mid_width;
 			    }
 			}
-		    }
-		}
+	            }
+	        }
 	      pango_layout_set_width (label->layout, width);
 	    }
 	}
@@ -1625,7 +1626,7 @@
       GtkTextDirection dir2 = GTK_TEXT_DIR_NONE;
       GdkGC *gc1 = NULL;
       GdkGC *gc2 = NULL;
-
+      
       keymap_direction =
 	(gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ?
 	GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
Index: gtk/gtklistitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklistitem.c,v
retrieving revision 1.31
diff -u -r1.31 gtklistitem.c
--- gtk/gtklistitem.c	2001/11/17 23:28:50	1.31
+++ gtk/gtklistitem.c	2001/11/18 05:35:00
@@ -450,22 +450,28 @@
   gdk_window_set_background (widget->window, 
 			     &widget->style->base[GTK_STATE_NORMAL]);
 }
-
 static void
 gtk_list_item_size_request (GtkWidget      *widget,
 			    GtkRequisition *requisition)
 {
   GtkBin *bin;
   GtkRequisition child_requisition;
+  gint focus_width;
+  gint focus_pad;
+  gboolean interior_focus;
 
   g_return_if_fail (GTK_IS_LIST_ITEM (widget));
   g_return_if_fail (requisition != NULL);
 
   bin = GTK_BIN (widget);
-
-  requisition->width = (GTK_CONTAINER (widget)->border_width +
-			widget->style->xthickness) * 2;
-  requisition->height = GTK_CONTAINER (widget)->border_width * 2;
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width,
+			"focus-padding", &focus_pad,
+			"interior_focus", &interior_focus, NULL);
+
+  requisition->width = 2 * (GTK_CONTAINER (widget)->border_width +
+			widget->style->xthickness + focus_width + focus_pad - 1);
+  requisition->height = 2 * (GTK_CONTAINER (widget)->border_width +
+			focus_width + focus_pad - 1);
 
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
     {
@@ -531,9 +537,12 @@
 		      GdkEventExpose *event)
 {
   GtkBin *bin;
+  gint focus_width;
 
   g_return_val_if_fail (widget != NULL, FALSE);
 
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
+  
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       bin = GTK_BIN (widget);
@@ -558,16 +567,17 @@
         {
           if (GTK_IS_LIST (widget->parent) && GTK_LIST (widget->parent)->add_mode)
             gtk_paint_focus (widget->style, widget->window,
-                             NULL, widget, "add-mode",
-                             0, 0,
-                             widget->allocation.width - 1,
-                             widget->allocation.height - 1);
+                             NULL, widget,
+			     GTK_WIDGET_STATE (widget), "add-mode",
+                             focus_width/2, focus_width/2,
+                             widget->allocation.width - focus_width,
+                             widget->allocation.height - focus_width);
           else
             gtk_paint_focus (widget->style, widget->window,
-                             NULL, widget, NULL,
-                             0, 0,
-                             widget->allocation.width - 1,
-                             widget->allocation.height - 1);
+                             NULL, widget, GTK_WIDGET_STATE (widget), NULL,
+                             focus_width/2, focus_width/2,
+                             widget->allocation.width - focus_width,
+                             widget->allocation.height - focus_width);
         }
     }
 
Index: gtk/gtknotebook.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.c,v
retrieving revision 1.106
diff -u -r1.106 gtknotebook.c
--- gtk/gtknotebook.c	2001/11/17 23:28:50	1.106
+++ gtk/gtknotebook.c	2001/11/18 05:35:03
@@ -41,7 +41,6 @@
 #define TAB_CURVATURE  1
 #define ARROW_SIZE     12
 #define ARROW_SPACING  0
-#define FOCUS_WIDTH    1
 #define NOTEBOOK_INIT_SCROLL_DELAY (200)
 #define NOTEBOOK_SCROLL_DELAY      (100)
 
@@ -900,10 +899,12 @@
   GtkRequisition child_requisition;
   gboolean switch_page = FALSE;
   gint vis_pages;
+  gint focus_width;
 
   g_return_if_fail (GTK_IS_NOTEBOOK (widget));
   g_return_if_fail (requisition != NULL);
 
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
   notebook = GTK_NOTEBOOK (widget);
   widget->requisition.width = 0;
   widget->requisition.height = 0;
@@ -974,14 +975,14 @@
 		    case GTK_POS_TOP:
 		    case GTK_POS_BOTTOM:
 		      page->requisition.height += 2 * (notebook->tab_vborder +
-						       FOCUS_WIDTH);
+						       focus_width);
 		      tab_height = MAX (tab_height, page->requisition.height);
 		      tab_max = MAX (tab_max, page->requisition.width);
 		      break;
 		    case GTK_POS_LEFT:
 		    case GTK_POS_RIGHT:
 		      page->requisition.width += 2 * (notebook->tab_hborder +
-						      FOCUS_WIDTH);
+						      focus_width);
 		      tab_width = MAX (tab_width, page->requisition.width);
 		      tab_max = MAX (tab_max, page->requisition.height);
 		      break;
@@ -1006,7 +1007,7 @@
 		      widget->requisition.width < tab_width)
 		    tab_height = MAX (tab_height, ARROW_SIZE);
 
-		  padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH +
+		  padding = 2 * (TAB_CURVATURE + focus_width +
 				 notebook->tab_hborder) - TAB_OVERLAP;
 		  tab_max += padding;
 		  while (children)
@@ -1049,7 +1050,7 @@
 		      widget->requisition.height < tab_height)
 		    tab_width = MAX (tab_width, ARROW_SPACING +2 * ARROW_SIZE);
 
-		  padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH +
+		  padding = 2 * (TAB_CURVATURE + focus_width +
 				 notebook->tab_vborder) - TAB_OVERLAP;
 		  tab_max += padding;
 
@@ -1565,6 +1566,8 @@
 gtk_notebook_draw_focus (GtkWidget *widget)
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+  gint focus_width;
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
 
   if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs &&
       notebook->focus_tab)
@@ -1574,10 +1577,10 @@
 
       page = notebook->focus_tab->data;
 
-      area.x = page->tab_label->allocation.x - 1;
-      area.y = page->tab_label->allocation.y - 1;
-      area.width = page->tab_label->allocation.width + 2;
-      area.height = page->tab_label->allocation.height + 2;
+      area.x = page->tab_label->allocation.x - focus_width;
+      area.y = page->tab_label->allocation.y - focus_width;
+      area.width = page->tab_label->allocation.width + 2*focus_width;
+      area.height = page->tab_label->allocation.height + 2*focus_width;
 
       gtk_notebook_draw_tab (GTK_NOTEBOOK (widget), page, &area);
     }
@@ -2063,27 +2066,30 @@
   if (GTK_WIDGET_DRAWABLE (notebook) && notebook->show_tabs) 
     {
       GdkRectangle area;
+      gint focus_width;
 
+      gtk_widget_style_get (GTK_WIDGET (notebook), "focus-line-width", &focus_width, NULL);
+
       if (notebook->focus_tab)
 	{
 	  GtkNotebookPage *page;
 
 	  page = notebook->focus_tab->data;
 
-	  area.x = page->tab_label->allocation.x - 1;
-	  area.y = page->tab_label->allocation.y - 1;
-	  area.width = page->tab_label->allocation.width + 2;
-	  area.height = page->tab_label->allocation.height + 2;
+	  area.x = page->tab_label->allocation.x - focus_width;
+	  area.y = page->tab_label->allocation.y - focus_width;
+	  area.width = page->tab_label->allocation.width + 2 * focus_width;
+	  area.height = page->tab_label->allocation.height + 2 * focus_width;
 
 	  gtk_notebook_draw_tab (notebook, page, &area);
 	}
 
       if (old_page)
 	{
-	  area.x = old_page->tab_label->allocation.x - 1;
-	  area.y = old_page->tab_label->allocation.y - 1;
-	  area.width = old_page->tab_label->allocation.width + 2;
-	  area.height = old_page->tab_label->allocation.height + 2;
+	  area.x = old_page->tab_label->allocation.x - focus_width;
+	  area.y = old_page->tab_label->allocation.y - focus_width;
+	  area.width = old_page->tab_label->allocation.width + 2 * focus_width;
+	  area.height = old_page->tab_label->allocation.height + 2 * focus_width;
 
 	  gtk_notebook_draw_tab (notebook, old_page, &area);
 	}
@@ -2547,12 +2553,16 @@
       if ((GTK_WIDGET_HAS_FOCUS (widget)) &&
 	  notebook->focus_tab && (notebook->focus_tab->data == page))
 	{
+          gint focus_width;
+	  gint focus_halfwidth;
+	  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
+	  focus_halfwidth = MAX (focus_width/2, (focus_width + 1)/2);
 	  gtk_paint_focus (widget->style, widget->window,
-			   area, widget, "tab",
-			   page->tab_label->allocation.x - 1,
-			   page->tab_label->allocation.y - 1,
-			   page->tab_label->allocation.width + 1,
-			   page->tab_label->allocation.height + 1);
+			   area, widget, GTK_WIDGET_STATE (widget), "tab",
+			   page->tab_label->allocation.x - focus_halfwidth,
+			   page->tab_label->allocation.y - focus_halfwidth,
+			   page->tab_label->allocation.width + focus_width,
+			   page->tab_label->allocation.height + focus_width);
 	}
       if (gtk_widget_intersect (page->tab_label, area, &child_area) &&
           GTK_WIDGET_DRAWABLE (page->tab_label))
@@ -3093,13 +3103,15 @@
   gint xthickness;
   gint ythickness;
   gint padding;
+  gint focus_width;
 
   g_return_if_fail (notebook != NULL);
   g_return_if_fail (page != NULL);
   g_return_if_fail (allocation != NULL);
 
   widget = GTK_WIDGET (notebook);
-
+  
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
   xthickness = widget->style->xthickness;
   ythickness = widget->style->ythickness;
 
@@ -3174,10 +3186,10 @@
     {
     case GTK_POS_TOP:
     case GTK_POS_BOTTOM:
-      padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_hborder;
+      padding = TAB_CURVATURE + focus_width + notebook->tab_hborder;
       if (page->fill)
 	{
-	  child_allocation.x = (xthickness + FOCUS_WIDTH +
+	  child_allocation.x = (xthickness + focus_width +
 				notebook->tab_hborder);
 	  child_allocation.width = MAX (1, (page->allocation.width -
 					    2 * child_allocation.x));
@@ -3190,16 +3202,16 @@
 				 tab_requisition.width) / 2);
 	  child_allocation.width = tab_requisition.width;
 	}
-      child_allocation.y = (notebook->tab_vborder + FOCUS_WIDTH +
+      child_allocation.y = (notebook->tab_vborder + focus_width +
 			    page->allocation.y);
       if (notebook->tab_pos == GTK_POS_TOP)
 	child_allocation.y += ythickness;
-      child_allocation.height = MAX (1, (page->allocation.height - ythickness -
-					 2 * (notebook->tab_vborder + FOCUS_WIDTH)));
+      child_allocation.height = MAX (1, (((gint) page->allocation.height) - ythickness -
+					 2 * (notebook->tab_vborder + focus_width)));
       break;
     case GTK_POS_LEFT:
     case GTK_POS_RIGHT:
-      padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_vborder;
+      padding = TAB_CURVATURE + focus_width + notebook->tab_vborder;
       if (page->fill)
 	{
 	  child_allocation.y = ythickness + padding;
@@ -3213,11 +3225,11 @@
 						      tab_requisition.height) / 2);
 	  child_allocation.height = tab_requisition.height;
 	}
-      child_allocation.x = page->allocation.x + notebook->tab_hborder + FOCUS_WIDTH;
+      child_allocation.x = page->allocation.x + notebook->tab_hborder + focus_width;
       if (notebook->tab_pos == GTK_POS_LEFT)
 	child_allocation.x += xthickness;
-      child_allocation.width = MAX (1, (page->allocation.width - xthickness -
-					2 * (notebook->tab_hborder + FOCUS_WIDTH)));
+      child_allocation.width = MAX (1, (((gint) page->allocation.width) - xthickness -
+					2 * (notebook->tab_hborder + focus_width)));
       break;
     }
 
Index: gtk/gtkoptionmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkoptionmenu.c,v
retrieving revision 1.56
diff -u -r1.56 gtkoptionmenu.c
--- gtk/gtkoptionmenu.c	2001/11/17 23:28:50	1.56
+++ gtk/gtkoptionmenu.c	2001/11/18 05:35:04
@@ -431,10 +431,14 @@
 {
   GtkOptionMenu *option_menu = GTK_OPTION_MENU (widget);
   GtkOptionMenuProps props;
+  gint focus_width;
+  gint focus_pad;
   gint tmp;
   GtkRequisition child_requisition = { 0, 0 };
       
   gtk_option_menu_get_props (option_menu, &props);
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width,
+			"focus-padding", &focus_pad, NULL);
  
   if (GTK_BIN (option_menu)->child && GTK_WIDGET_VISIBLE (GTK_BIN (option_menu)->child))
     {
@@ -449,11 +453,11 @@
 			MAX (child_requisition.width, option_menu->width) +
  			props.indicator_size.width +
  			props.indicator_spacing.left + props.indicator_spacing.right +
-			CHILD_LEFT_SPACING + CHILD_RIGHT_SPACING + 2);
+			CHILD_LEFT_SPACING + CHILD_RIGHT_SPACING + focus_width*2);
   requisition->height = ((GTK_CONTAINER (widget)->border_width +
 			  GTK_WIDGET (widget)->style->ythickness) * 2 +
 			 MAX (child_requisition.height, option_menu->height) +
-			 CHILD_TOP_SPACING + CHILD_BOTTOM_SPACING + 2);
+			 CHILD_TOP_SPACING + CHILD_BOTTOM_SPACING + 2*focus_width);
 
   tmp = (requisition->height - option_menu->height +
 	 props.indicator_size.height + props.indicator_spacing.top + props.indicator_spacing.bottom);
@@ -505,6 +509,8 @@
   GdkRectangle button_area;
   GtkOptionMenuProps props;
   gint border_width;
+  gint focus_width;
+  gint focus_pad;
 
   g_return_if_fail (GTK_IS_OPTION_MENU (widget));
   g_return_if_fail (area != NULL);
@@ -512,6 +518,8 @@
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       border_width = GTK_CONTAINER (widget)->border_width;
+      gtk_widget_style_get (widget, "focus-line-width", &focus_width,
+			    "focus-padding", &focus_pad, NULL);
       gtk_option_menu_get_props (GTK_OPTION_MENU (widget), &props);
 
       button_area.x = widget->allocation.x + border_width;
@@ -521,12 +529,12 @@
 
       if (!props.interior_focus)
 	{
-	  button_area.x += 1;
-	  button_area.y += 1;
-	  button_area.width -= 2;
-	  button_area.height -= 2;
+	  button_area.x += focus_width + focus_pad;
+	  button_area.y += focus_width + focus_pad;
+	  button_area.width -= 2*(focus_width + focus_pad);
+	  button_area.height -= 2*(focus_width + focus_pad);
 	}
-
+      
       gtk_paint_box (widget->style, widget->window,
 		     GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT,
 		     area, widget, "optionmenu",
@@ -546,22 +554,25 @@
 	{
 	  if (props.interior_focus)
 	    {
-	      button_area.x += widget->style->xthickness + 1;
-	      button_area.y += widget->style->ythickness + 1;
-	      button_area.width -= 2 * (widget->style->xthickness + 1)
-		+ props.indicator_spacing.left + props.indicator_spacing.right + props.indicator_size.width;
-	      button_area.height -= 2 * (widget->style->ythickness + 1);
+	      button_area.x += widget->style->xthickness + 1 + focus_width/2;
+	      button_area.y += widget->style->ythickness + 1 + focus_width/2;
+	      button_area.width -= 2 * (widget->style->xthickness) +
+		      props.indicator_spacing.left +
+		      props.indicator_spacing.right +
+		      props.indicator_size.width + focus_width;
+	      button_area.height -= 2 * (widget->style->ythickness) + focus_width;
 	    }
 	  else
 	    {
-	      button_area.x -= 1;
-	      button_area.y -= 1;
-	      button_area.width += 2;
-	      button_area.height += 2;
+	      gint focus_halfwidth = MAX (focus_width/2, (focus_width+1)/2);
+	      button_area.x -= focus_halfwidth;
+	      button_area.y -= focus_halfwidth;
+	      button_area.width += focus_width + 2 * focus_pad;
+	      button_area.height += focus_width + 2 * focus_pad;
 	    }
 	    
 	  gtk_paint_focus (widget->style, widget->window,
-			   area, widget, "button",
+			   area, widget, GTK_WIDGET_STATE (widget), "button",
 			   button_area.x, 
 			   button_area.y, 
 			   button_area.width - 1,
Index: gtk/gtkradiobutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkradiobutton.c,v
retrieving revision 1.36
diff -u -r1.36 gtkradiobutton.c
--- gtk/gtkradiobutton.c	2001/11/16 22:56:19	1.36
+++ gtk/gtkradiobutton.c	2001/11/18 05:35:04
@@ -587,6 +587,9 @@
   GdkRectangle new_area;
   gint x, y;
   gint indicator_size, indicator_spacing;
+  gint focus_width;
+  gint focus_pad = DEFAULT_FOCUS_PAD;
+  gboolean interior_focus;
 
   g_return_if_fail (GTK_IS_RADIO_BUTTON (check_button));
 
@@ -596,6 +599,9 @@
       button = GTK_BUTTON (check_button);
       toggle_button = GTK_TOGGLE_BUTTON (check_button);
 
+      gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			    "focus-line-width", &focus_width, NULL);
+
       state_type = GTK_WIDGET_STATE (widget);
       if ((state_type != GTK_STATE_NORMAL) &&
 	  (state_type != GTK_STATE_PRELIGHT))
@@ -620,6 +626,11 @@
       
       x = widget->allocation.x + indicator_spacing + GTK_CONTAINER (widget)->border_width;
       y = widget->allocation.y + (widget->allocation.height - indicator_size) / 2;
+
+      if (!interior_focus)
+        {
+          x += focus_width + focus_pad;      
+        }
       
       if (GTK_TOGGLE_BUTTON (widget)->active)
 	shadow_type = GTK_SHADOW_IN;
Index: gtk/gtkrange.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrange.c,v
retrieving revision 1.68
diff -u -r1.68 gtkrange.c
--- gtk/gtkrange.c	2001/11/17 23:28:50	1.68
+++ gtk/gtkrange.c	2001/11/18 05:35:06
@@ -696,14 +696,23 @@
   (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
+
 static void
 gtk_range_size_request (GtkWidget      *widget,
                         GtkRequisition *requisition)
 {
   GtkRange *range;
   gint slider_width, stepper_size, trough_border, stepper_spacing;
+  gint focus_width;
+  gint focus_pad;
+  gboolean interior_focus;
+  gint focus_extra = 0;
   GdkRectangle range_rect;
   GtkBorder border;
+
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width,
+			"focus-padding", &focus_pad,
+			"interior_focus", &interior_focus, NULL);
   
   range = GTK_RANGE (widget);
   
@@ -714,8 +723,13 @@
                           slider_width, stepper_size, trough_border, stepper_spacing,
                           &range_rect, &border, NULL, NULL);
 
-  requisition->width = range_rect.width + border.left + border.right;
-  requisition->height = range_rect.height + border.top + border.bottom;
+  /* this preserves previous sizing for exterior focus / no pad case */
+  if (!interior_focus && (focus_pad > 0))
+    {
+      focus_extra = 2 * (focus_pad + focus_width);
+    }
+  requisition->width = range_rect.width + border.left + border.right + focus_extra;
+  requisition->height = range_rect.height + border.top + border.bottom + focus_extra;
 }
 
 static void
@@ -878,10 +892,18 @@
   GtkStateType state;
   GdkRectangle expose_area;	/* Relative to widget->allocation */
   GdkRectangle area;
+  gint focus_width;
+  gint focus_pad;
+  gboolean interior_focus;
+  gint focus_tmp = 0; 
   
   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			"focus-padding", &focus_pad,
+			"focus-line-width", &focus_width, NULL);
+  
   range = GTK_RANGE (widget);
 
   expose_area = event->area;
@@ -902,6 +924,10 @@
   if (gdk_rectangle_intersect (&expose_area, &range->range_rect,
                                &area))
     {
+      if (!interior_focus && (focus_pad > 0))
+        {
+          focus_tmp = focus_pad + focus_width;
+        }
       area.x += widget->allocation.x;
       area.y += widget->allocation.y;
       
@@ -915,16 +941,17 @@
                      range->range_rect.width,
                      range->range_rect.height);
       
-                 
       if (sensitive &&
           GTK_WIDGET_HAS_FOCUS (range))
-        gtk_paint_focus (widget->style,
+        {
+          gtk_paint_focus (widget->style,
                          widget->window,
-                         &area, widget, "trough",
-                         widget->allocation.x + range->range_rect.x,
-                         widget->allocation.y + range->range_rect.y,
-                         range->range_rect.width,
-                         range->range_rect.height);
+                         &area, widget, GTK_WIDGET_STATE (widget), "trough",
+                         range->range_rect.x + focus_width/2,
+                         range->range_rect.y + focus_width/2,
+                         range->range_rect.width - focus_width,
+                         range->range_rect.height - focus_width);
+	}
     }
 
   if (!sensitive)
Index: gtk/gtksettings.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtksettings.c,v
retrieving revision 1.20
diff -u -r1.20 gtksettings.c
--- gtk/gtksettings.c	2001/11/13 00:53:36	1.20
+++ gtk/gtksettings.c	2001/11/18 05:35:06
@@ -188,8 +188,7 @@
 								  NULL,
 								  G_PARAM_READWRITE),
                                              NULL);
-  g_assert (result == PROP_KEY_THEME_NAME);    
-
+  g_assert (result == PROP_KEY_THEME_NAME);
   result = settings_install_property_parser (class,
                                              g_param_spec_string ("gtk-menu-bar-accel",
                                                                   _("Menu bar accelerator"),
Index: gtk/gtkspinbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkspinbutton.c,v
retrieving revision 1.79
diff -u -r1.79 gtkspinbutton.c
--- gtk/gtkspinbutton.c	2001/11/17 23:28:51	1.79
+++ gtk/gtkspinbutton.c	2001/11/18 05:35:08
@@ -572,6 +572,7 @@
   GtkEntry *entry;
   GtkSpinButton *spin_button;
   gint arrow_size;
+  gint focus_width;
   
   g_return_if_fail (requisition != NULL);
   g_return_if_fail (GTK_IS_SPIN_BUTTON (widget));
@@ -581,6 +582,7 @@
   arrow_size = spin_button_get_arrow_size (spin_button);
   
   GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
+  gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL);
 
   if (entry->width_chars < 0)
     {
@@ -617,11 +619,14 @@
       w = MIN (string_len, max_string_len) * digit_width;
       width = MAX (width, w);
       
-      requisition->width = (width + arrow_size +
-			    2 * widget->style->xthickness);
+      requisition->width = width + arrow_size +
+			    2 * (widget->style->xthickness + (focus_width - 1));
     }
   else
-    requisition->width += arrow_size + 2 * widget->style->xthickness;
+    {
+      requisition->width += arrow_size + 2 *
+	      (widget->style->xthickness + (focus_width - 1));
+    }
 }
 
 static void
Index: gtk/gtkstyle.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.88
diff -u -r1.88 gtkstyle.c
--- gtk/gtkstyle.c	2001/11/16 15:20:27	1.88
+++ gtk/gtkstyle.c	2001/11/18 05:35:11
@@ -241,6 +241,7 @@
 					 GdkWindow       *window,
 					 GdkRectangle    *area,
 					 GtkWidget       *widget,
+					 GtkStateType     state_type,
 					 const gchar     *detail,
 					 gint             x,
 					 gint             y,
@@ -1061,7 +1062,7 @@
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
   
-  GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, NULL, NULL, NULL, x, y, width, height);
+  GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, NULL, NULL, GTK_STATE_NORMAL, NULL, x, y, width, height);
 }
 
 void 
@@ -3780,6 +3781,7 @@
 			GdkWindow     *window,
 			GdkRectangle  *area,
 			GtkWidget     *widget,
+			GtkStateType   state_type,
 			const gchar   *detail,
 			gint           x,
 			gint           y,
@@ -3787,18 +3789,30 @@
 			gint           height)
 {
   GdkPoint points[5];
+  gint8    *dash_list = "\1\1";
+  gint     line_width = 1;
+  GValue   value = { 0, };
+  GdkGC    *gc;
+
+  gc = style->fg_gc[state_type];
+
+  gtk_widget_style_get (widget,
+			"focus-line-width", &line_width,
+			"focus-line-pattern", (gchar *)&dash_list,
+			NULL);
+
   
   sanitize_size (window, &width, &height);
   
   if (area)
-    gdk_gc_set_clip_rectangle (style->black_gc, area);
+    gdk_gc_set_clip_rectangle (gc, area);
 
-  gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
+  gdk_gc_set_line_attributes (gc, line_width, GDK_LINE_ON_OFF_DASH, 0, 0);
 
   if (detail && !strcmp (detail, "add-mode"))
-    gdk_gc_set_dashes (style->black_gc, 0, "\4\4", 2);
+    gdk_gc_set_dashes (gc, 0, "\4\4", 2);
   else
-    gdk_gc_set_dashes (style->black_gc, 0, "\1\1", 2);
+    gdk_gc_set_dashes (gc, 0, dash_list, strlen (dash_list));
 
   points[0].x = x;
   points[0].y = y;
@@ -3810,11 +3824,11 @@
   points[3].y = y + height;
   points[4] = points[0];
   
-  gdk_draw_polygon (window, style->black_gc, FALSE, points, 4);
-  gdk_gc_set_line_attributes (style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
+  gdk_draw_polygon (window, gc, FALSE, points, 4);
+  gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
 
   if (area)
-    gdk_gc_set_clip_rectangle (style->black_gc, NULL);
+    gdk_gc_set_clip_rectangle (gc, NULL);
 }
 
 static void 
@@ -4849,6 +4863,7 @@
                  GdkWindow     *window,
                  GdkRectangle  *area,
                  GtkWidget     *widget,
+		 GtkStateType   state_type,
                  const gchar   *detail,
                  gint           x,
                  gint           y,
@@ -4858,7 +4873,7 @@
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
   
-  GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, detail, x, y, width, height);
+  GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, state_type, detail, x, y, width, height);
 }
 
 void
@@ -5077,11 +5092,17 @@
 			    GdkRectangle     *location,
 			    GtkTextDirection  dir)
 {
-  gint stem_width = location->height / 30 + 1;
+  gint stem_width;
   gint arrow_width = stem_width + 1;
   gint x, y;
   gint i;
-
+  
+  stem_width = (gint) (location->height / 30);
+  if (stem_width < 1)
+    {
+      stem_width = 1;
+    }
+  
   for (i = 0; i < stem_width; i++)
     gdk_draw_line (drawable, gc,
 		   location->x + i - stem_width / 2, location->y,
Index: gtk/gtkstyle.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.h,v
retrieving revision 1.33
diff -u -r1.33 gtkstyle.h
--- gtk/gtkstyle.h	2001/10/22 14:31:05	1.33
+++ gtk/gtkstyle.h	2001/11/18 05:35:11
@@ -342,6 +342,7 @@
 				 GdkWindow		*window,
 				 GdkRectangle		*area,
 				 GtkWidget		*widget,
+                                 GtkStateType            state_type,
 				 const gchar		*detail,
 				 gint			 x,
 				 gint			 y,
@@ -777,6 +778,7 @@
 			   GdkWindow       *window,
 			   GdkRectangle    *area,
 			   GtkWidget       *widget,
+			   GtkStateType     state_type,
 			   const gchar     *detail,
 			   gint             x,
 			   gint             y,
Index: gtk/gtktext.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktext.c,v
retrieving revision 1.108
diff -u -r1.108 gtktext.c
--- gtk/gtktext.c	2001/11/17 23:28:51	1.108
+++ gtk/gtktext.c	2001/11/18 05:35:14
@@ -1527,7 +1527,7 @@
 	  yextra -= 1;
 
 	  gtk_paint_focus (widget->style, widget->window,
-			   NULL, widget, "text",
+			   NULL, widget, GTK_WIDGET_STATE (widget), "text",
 			   0, 0,
 			   widget->allocation.width - 1,
 			   widget->allocation.height - 1);
Index: gtk/gtktextview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextview.c,v
retrieving revision 1.146
diff -u -r1.146 gtktextview.c
--- gtk/gtktextview.c	2001/11/17 23:28:51	1.146
+++ gtk/gtktextview.c	2001/11/18 05:35:19
@@ -131,6 +131,7 @@
   PROP_INDENT,
   PROP_TABS,
   PROP_CURSOR_VISIBLE,
+  PROP_CURSOR_THICKNESS,
   LAST_PROP
 };
 
@@ -614,7 +615,6 @@
 							 TRUE,
 							 G_PARAM_READWRITE));
 
-  
   /*
    * Style properties
    */
@@ -2427,8 +2427,6 @@
           GtkRequisition child_req;
           GtkRequisition old_req;
 
-          gtk_widget_get_child_requisition (child->widget, &old_req);
-          
           gtk_widget_size_request (child->widget, &child_req);
 
           gtk_widget_get_child_requisition (child->widget, &child_req);
@@ -2588,6 +2586,7 @@
   GdkRectangle top_rect;
   GdkRectangle bottom_rect;
   gint focus_edge_width;
+  gint focus_width;
   gboolean interior_focus;
   gboolean size_changed;
   
@@ -2612,12 +2611,13 @@
    * windows get at least a 1x1 allocation.
    */
 
-  gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL);
-  
+  gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			        "focus-line-width", &focus_width, NULL);
+
   if (interior_focus)
     focus_edge_width = 0;
   else
-    focus_edge_width = 1;
+    focus_edge_width = focus_width;
   
   width = allocation->width - focus_edge_width * 2 - GTK_CONTAINER (text_view)->border_width * 2;
 
@@ -3786,7 +3786,7 @@
       if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
         {          
           gtk_paint_focus (widget->style, widget->window,
-                           NULL, widget, "textview",
+                           NULL, widget, GTK_WIDGET_STATE (widget), "textview",
                            0, 0,
                            widget->allocation.width - 1,
                            widget->allocation.height - 1);
Index: gtk/gtktogglebutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktogglebutton.c,v
retrieving revision 1.43
diff -u -r1.43 gtktogglebutton.c
--- gtk/gtktogglebutton.c	2001/11/17 23:28:51	1.43
+++ gtk/gtktogglebutton.c	2001/11/18 05:35:19
@@ -35,6 +35,9 @@
 #define DEFAULT_TOP_POS   4
 #define DEFAULT_SPACING   7
 
+static GtkBorder default_default_border = { 1, 1, 1, 1 };
+static GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
+
 enum {
   TOGGLED,
   LAST_SIGNAL
@@ -262,8 +265,36 @@
 
   if (toggle_button->draw_indicator != draw_indicator)
     {
-      toggle_button->draw_indicator = draw_indicator;
+      if (GTK_WIDGET_REALIZED (toggle_button))
+	{
+	  gboolean visible = GTK_WIDGET_VISIBLE (toggle_button);
+
+	  if (visible)
+	    gtk_widget_hide (widget);
+
+	  gtk_widget_unrealize (widget);
+	  toggle_button->draw_indicator = draw_indicator;
 
+	  if (toggle_button->draw_indicator)
+	    GTK_WIDGET_SET_FLAGS (toggle_button, GTK_NO_WINDOW);
+	  else
+	    GTK_WIDGET_UNSET_FLAGS (toggle_button, GTK_NO_WINDOW);
+	  
+	  gtk_widget_realize (widget);
+
+	  if (visible)
+	    gtk_widget_show (widget);
+	}
+      else
+	{
+	  toggle_button->draw_indicator = draw_indicator;
+
+	  if (toggle_button->draw_indicator)
+	    GTK_WIDGET_SET_FLAGS (toggle_button, GTK_NO_WINDOW);
+	  else
+	    GTK_WIDGET_UNSET_FLAGS (toggle_button, GTK_NO_WINDOW);
+	}
+
       if (GTK_WIDGET_VISIBLE (toggle_button))
 	gtk_widget_queue_resize (GTK_WIDGET (toggle_button));
 
@@ -378,7 +409,11 @@
   GtkShadowType shadow_type;
   GtkStateType state_type;
   gint width, height;
+  GtkBorder default_border;
+  GtkBorder default_outside_border;
   gboolean interior_focus;
+  gint focus_width;
+  gint focus_pad;
   gint border_width;
   gint x, y;
 
@@ -388,8 +423,10 @@
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       border_width = GTK_CONTAINER (widget)->border_width;
-      
-      gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL);
+
+      gtk_widget_style_get (widget, "interior_focus", &interior_focus,
+			    "focus-line-width", &focus_width,
+			    "focus-padding", &focus_pad, NULL);
       
       x = widget->allocation.x + border_width;
       y = widget->allocation.y + border_width;
@@ -407,7 +444,7 @@
 
       if (GTK_WIDGET_CAN_DEFAULT (widget))
         {
-          x += widget->style->xthickness;
+	  x += widget->style->xthickness;
           y += widget->style->ythickness;
           width -= 2 * x + DEFAULT_SPACING;
           height -= 2 * y + DEFAULT_SPACING;
@@ -417,10 +454,10 @@
 
       if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
 	{
-	  x += 1;
-	  y += 1;
-	  width -= 2;
-	  height -= 2;
+	  x += focus_width + focus_pad;
+	  y += focus_width + focus_pad;
+	  width -= 2 * (focus_width + focus_pad);
+	  height -= 2 * (focus_width + focus_pad);
 	}
 
       state_type = GTK_WIDGET_STATE (widget);
@@ -446,22 +483,25 @@
 	{
 	  if (interior_focus)
 	    {
-	      x += widget->style->xthickness + 1;
-	      y += widget->style->xthickness + 1;
-	      width -= 2 * (widget->style->xthickness + 1);
-	      height -= 2 * (widget->style->ythickness + 1);
+	      gint focus_halfwidth = (focus_width+1)/2;
+	      x += widget->style->xthickness + focus_halfwidth + focus_pad;
+	      y += widget->style->xthickness + focus_halfwidth + focus_pad;
+	      width -= 2 * (widget->style->xthickness) + focus_width + 2 * focus_pad;
+	      height -= 2 * (widget->style->ythickness) + focus_width + 2 * focus_pad;
 	    }
 	  else
 	    {
-	      x -= 1;
-	      y -= 1;
-	      width += 2;
-	      height += 2;
+	      int focus_halfwidth = MAX (focus_width/2, (focus_width+1)/2);
+	      x -= focus_halfwidth + focus_pad;
+	      y -= focus_halfwidth + focus_pad;
+	      width += focus_width + focus_pad*2;
+	      height += focus_width + focus_pad*2;
 	    }
 
 	  gtk_paint_focus (widget->style, widget->window,
-			   area, widget, "togglebutton",
-			   x, y, width - 1, height - 1);
+			   area, widget, GTK_WIDGET_STATE (widget),
+			   "togglebutton",
+			   x, y, width, height);
 	}
     }
 }
Index: gtk/gtktreeitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeitem.c,v
retrieving revision 1.52
diff -u -r1.52 gtktreeitem.c
--- gtk/gtktreeitem.c	2001/11/17 23:28:51	1.52
+++ gtk/gtktreeitem.c	2001/11/18 05:35:20
@@ -665,7 +665,8 @@
 
       if (GTK_WIDGET_HAS_FOCUS (widget))
 	gtk_paint_focus (widget->style, widget->window,
-			 NULL, widget, "treeitem",
+			 NULL, widget,
+			 GTK_WIDGET_STATE (widget), "treeitem",
 			 0, 0,
 			 widget->allocation.width - 1,
 			 widget->allocation.height - 1);
Index: gtk/gtktreeview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeview.c,v
retrieving revision 1.174
diff -u -r1.174 gtktreeview.c
--- gtk/gtktreeview.c	2001/11/17 23:28:51	1.174
+++ gtk/gtktreeview.c	2001/11/18 05:35:26
@@ -394,7 +394,6 @@
 static GtkContainerClass *parent_class = NULL;
 static guint tree_view_signals [LAST_SIGNAL] = { 0 };
 
-
 
 /* GType Methods
  */
@@ -917,7 +916,6 @@
   tree_view->priv->search_equal_func = gtk_tree_view_search_equal_func;
 }
 
-
 
 /* GObject Methods
  */
@@ -2495,6 +2493,7 @@
   gint vertical_separator;
   gint horizontal_separator;
   gboolean allow_rules;
+  gint focus_width;
 
   g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
 
@@ -2504,6 +2503,7 @@
 			"horizontal_separator", &horizontal_separator,
 			"vertical_separator", &vertical_separator,
 			"allow_rules", &allow_rules,
+			"focus-line-width", &focus_width,
 			NULL);
 
   if (tree_view->priv->tree == NULL)
@@ -2774,9 +2774,10 @@
 			       tree_view->priv->bin_window,
 			       NULL,
 			       widget,
+			       GTK_WIDGET_STATE (widget),
 			       "treeview-drop-indicator",
-			       0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node),
-			       width - 1, BACKGROUND_HEIGHT (node) - 1);
+			       focus_width/2, BACKGROUND_FIRST_PIXEL (tree_view, tree, node)+focus_width/2,
+			       width - focus_width, BACKGROUND_HEIGHT (node) - focus_width);
 
               break;
             }
Index: gtk/gtktreeviewcolumn.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeviewcolumn.c,v
retrieving revision 1.80
diff -u -r1.80 gtktreeviewcolumn.c
--- gtk/gtktreeviewcolumn.c	2001/11/17 23:28:51	1.80
+++ gtk/gtktreeviewcolumn.c	2001/11/18 05:35:28
@@ -2149,6 +2149,8 @@
   gint full_requested_width = 0;
   gint extra_space;
   gint min_x, min_y, max_x, max_y;
+  gint focus_width;
+  gint cell_width, cell_height;
 
   min_x = G_MAXINT;
   min_y = G_MAXINT;
@@ -2157,6 +2159,8 @@
 
   real_cell_area = *cell_area;
 
+  gtk_widget_style_get (GTK_WIDGET (tree_column->button), "focus-line-width", &focus_width, NULL);
+
   /* Find out how my extra space we have to allocate */
   for (list = tree_column->cell_list; list; list = list->next)
     {
@@ -2190,8 +2194,17 @@
 
       real_cell_area.width = info->requested_width +
 	(info->expand?extra_space:0);
+
       if (render)
 	{
+          gtk_cell_renderer_get_size (info->cell,
+				      tree_column->tree_view,
+				      NULL,
+				      NULL,
+				      NULL,
+				      &cell_width,
+				      &cell_height);
+          real_cell_area.y += (real_cell_area.height - cell_height)/2;
 	  gtk_cell_renderer_render (info->cell,
 				    window,
 				    tree_column->tree_view,
@@ -2219,7 +2232,7 @@
 	  if (max_y < real_cell_area.y + y_offset + height)
 	    max_y = real_cell_area.y + y_offset + height;
 	}
-      real_cell_area.x += (info->requested_width + tree_column->spacing);
+      real_cell_area.x += (info->requested_width + tree_column->spacing + focus_width - 1);
     }
   for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
     {
@@ -2249,17 +2262,18 @@
       if (min_x >= max_x || min_y >= max_y)
 	{
 	  *focus_rectangle = *cell_area;
-	  focus_rectangle->x -= 1;
-	  focus_rectangle->y -= 1;
-	  focus_rectangle->width += 2;
-	  focus_rectangle->height += 2;
+	  focus_rectangle->x += focus_width/2;
+	  focus_rectangle->y += focus_width/2;
+	  focus_rectangle->width -= focus_width;
+	  focus_rectangle->height -= focus_width;
 	}
       else
 	{
-	  focus_rectangle->x = min_x - 1;
-	  focus_rectangle->y = min_y - 1;
-	  focus_rectangle->width = (max_x - min_x) + 2;
-	  focus_rectangle->height = (max_y - min_y) + 2;
+	  focus_rectangle->x = min_x - focus_width/2;
+	  focus_rectangle->y = MAX (cell_area->y + focus_width/2,
+				    min_y - focus_width/2);
+	  focus_rectangle->width = (max_x - min_x) + focus_width;
+	  focus_rectangle->height = cell_area->height - focus_width;
 	}
     }
 }
@@ -2365,22 +2379,28 @@
 				      GdkRectangle            *expose_area,
 				      guint                    flags)
 {
+  gint focus_width;	
   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+
+  gtk_widget_style_get (GTK_WIDGET (tree_column->button), "focus-line-width", &focus_width, NULL);
   if (tree_column->editable_widget)
     {
       /* This function is only called on the editable row when editing.
        */
-
-      gtk_paint_focus (tree_column->tree_view->style,
-		       window,
-		       NULL,
-		       tree_column->tree_view,
-		       "treeview",
-		       cell_area->x - 1,
-		       cell_area->y - 1,
-		       cell_area->width + 2 - 1,
-		       cell_area->height + 2 - 1);
-      
+      /* don't call this, since if interior_focus=TRUE we use the caret,
+       * and if interior_focus=FALSE the entry widget will draw its own
+       *	 focus rectangle..
+       * gtk_paint_focus (tree_column->tree_view->style,
+       *		       window,
+       *	       NULL,
+       *	       tree_column->tree_view,
+       *	       GTK_STATE_NORMAL,
+       *	       "treeview",
+       *	       cell_area->x - focus_width/2,
+       *	       cell_area->y - focus_width/2,
+       *	       cell_area->width + focus_width - 1,
+       *	       cell_area->height + focus_width - 1);
+       */
     }
   else
     {
@@ -2398,11 +2418,13 @@
 		       window,
 		       NULL,
 		       tree_column->tree_view,
+		       (flags && GTK_CELL_RENDERER_SELECTED) ?
+		                GTK_STATE_SELECTED : GTK_STATE_NORMAL,
 		       "treeview",
 		       focus_rectangle.x,
 		       focus_rectangle.y,
-		       focus_rectangle.width - 1,
-		       focus_rectangle.height - 1);
+		       focus_rectangle.width,
+		       focus_rectangle.height);
     }
 }
 
Index: gtk/gtkwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.c,v
retrieving revision 1.266
diff -u -r1.266 gtkwidget.c
--- gtk/gtkwidget.c	2001/11/17 23:28:51	1.266
+++ gtk/gtkwidget.c	2001/11/18 05:35:32
@@ -1054,6 +1054,27 @@
 								 _("Whether to draw the focus indicator inside widgets."),
 								 TRUE,
 								 G_PARAM_READABLE));
+
+  gtk_widget_class_install_style_property (klass,
+					   g_param_spec_int ("focus-line-width",
+							     _("Focus linewidth"),
+							     _("Width, in pixels, of the line drawn to indicate widget focus"),
+							     0, 10, 1,
+							     G_PARAM_READWRITE));
+
+  gtk_widget_class_install_style_property (klass,
+					   g_param_spec_string ("focus-line-pattern",
+								_("Focus line dash pattern"),
+								_("Dash pattern used to draw default focus indication"),
+								"\1\1",
+								G_PARAM_READWRITE));
+  gtk_widget_class_install_style_property (klass,
+					   g_param_spec_int ("focus-padding",
+							     _("Focus padding"),
+							     _("Width, in pixels, between focus indication line and the widget 'box'"),
+							     0, 10, 0,
+							     G_PARAM_READWRITE));
+
 }
 
 static void
@@ -3461,7 +3482,7 @@
   g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
   
   window = gtk_widget_get_toplevel (widget);
-  
+
   if (window && GTK_WIDGET_TOPLEVEL (window))
     gtk_window_set_default (GTK_WINDOW (window), widget);
   else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]