Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Helps fix the one-frame delay problem when running Google Sketchup in Wine
# Fixes the view each time the view changes
require 'sketchup'
def refresh
UI.start_timer(0, false) {
Sketchup.active_model.active_view.invalidate.refresh
}
end
module NH
module ViewFix
@observer = nil
@selection_observer = nil
@model_observer = nil
@layer_observer = nil
@tool_observer = nil
@rendering_observer = nil
class MyViewObserver < Sketchup::ViewObserver
def onViewChanged( view )
puts "New View changed: #{view.inspect}"
refresh
end
end
class MySelectObserver < Sketchup::SelectionObserver
def onSelectionBulkChange(selection)
puts "MySelectObserver.onSelectionBulkChange"
refresh
end
def onSelectionCleared(selection)
puts "MySelectObserver.onSelectionBulkChange"
refresh
end
end
class MyModelObserver < Sketchup::ModelObserver
def onActivePathChanged(model)
puts "onActivePathChanged: #{model}"
refresh
end
def onEraseAll(model)
puts "onEraseAll: #{model}"
refresh
end
def onExplode(model)
puts "onExplode: #{model}"
refresh
end
def onExplode(model)
puts "onExplode: #{model}"
refresh
end
# def onPidChanged(model, old_pid, new_pid)
# puts "onPidChanged: #{model}, #{old_pid} => #{new_pid}"
# refresh
# end
def onTransactionCommit(model)
puts "onTransactionCommit: #{model}"
refresh
end
def onTransactionAbort(model)
puts "onTransactionAbort: #{model}"
refresh
end
def onTransactionRedo(model)
puts "onTransactionRedo: #{model}"
refresh
end
def onTransactionUndo(model)
puts "onTransactionUndo: #{model}"
refresh
end
def onDeleteModel(model)
puts "onDeleteModel: #{model}"
refresh
end
def onPlaceComponent(instance)
puts "onPlaceComponent: #{instance}"
refresh
end
end
class MyLayersObserver < Sketchup::LayersObserver
def onCurrentLayerChanged(layers, layer)
puts "onCurrentLayerChanged: #{layer.name}"
refresh
end
def onLayerAdded(layers, layer)
puts "onLayerAdded: #{layer.name}"
refresh
end
def onLayerChanged(layers, layer)
puts "onLayerChanged: #{layer.name}"
refresh
end
def onLayerRemoved(layers, layer)
puts "onLayerRemoved: #{layer.name}"
refresh
end
def onRemoveAllLayers(layers)
puts "onRemoveAllLayers: #{layers}"
refresh
end
end
class MyToolObserver < Sketchup::ToolsObserver
def onActiveToolChanged(tools, tool_name, tool_id)
puts "onActiveToolChanged: #{tool_name}"
refresh
end
def onToolStateChanged(tools, tool_name, tool_id, tool_state)
puts "onToolStateChanged: #{tool_name}"
refresh
end
end
class MyRenderingOptionsObserver < Sketchup::RenderingOptionsObserver
def onRenderingOptionsChanged(rendering_options, type)
puts "onRenderingOptionsChanged(#{rendering_options}, #{type})"
refresh
end
end
def self.fix_view
fix_view_disable
fix_view_enable
end
def self.is_fix_set
!!@observer
end
def self.fix_view_disable
# Remove old observers
Sketchup.active_model.active_view.remove_observer( @observer ) if @observer
@observer = nil
Sketchup.active_model.selection.remove_observer( @selection_observer ) if @selection_observer
@selection_observer = nil
Sketchup.active_model.remove_observer( @model_observer ) if @model_observer
@model_observer = nil
Sketchup.active_model.layers.remove_observer( @layer_observer ) if @layer_observer
@layer_observer = nil
Sketchup.active_model.tools.remove_observer( @tool_observer ) if @tool_observer
@tool_observer = nil
Sketchup.active_model.rendering_options.remove_observer( @rendering_observer ) if @rendering_observer
@rendering_observer = nil
end
def self.fix_view_enable
# Attach the observers.
@layer_observer = MyLayersObserver.new
Sketchup.active_model.layers.add_observer( @layer_observer )
@observer = MyViewObserver.new
Sketchup.active_model.active_view.add_observer( @observer )
@selection_observer = MySelectObserver.new
Sketchup.active_model.selection.add_observer(@selection_observer)
@tool_observer = MyToolObserver.new
Sketchup.active_model.tools.add_observer(@tool_observer)
@rendering_observer = MyRenderingOptionsObserver.new
Sketchup.active_model.rendering_options.add_observer(@rendering_observer)
@model_observer = MyModelObserver.new
Sketchup.active_model.add_observer(@model_observer)
end
end
end
cmd = UI::Command.new("Refresh delay fix for Wine") {
if NH::ViewFix.is_fix_set
NH::ViewFix.fix_view_disable
else
NH::ViewFix.fix_view_enable
end
}
cmd.menu_text = "Refresh delay fix for Wine"
cmd.set_validation_proc {
if NH::ViewFix.is_fix_set
MF_CHECKED
else
MF_UNCHECKED
end
}
UI.menu("Plugins").add_item cmd
class MyAppObserver < Sketchup::AppObserver
def onNewModel(model)
puts "onNewModel: #{model}"
NH::ViewFix.fix_view
end
def onOpenModel(model)
puts "onOpenModel: #{model}"
NH::ViewFix.fix_view
end
def expectsStartupModelNotifications
return true
end
end
# Attach the observer
Sketchup.add_observer(MyAppObserver.new)
@Royrdan
Copy link

Royrdan commented May 7, 2020

This works amazing. Thank you so much!
Im also having the same issue when it tries to highlight the snap location with the little circle. It does not update the screen but still snaps to corners or ends but does not show the little circle in the correct spot. Any chance you have the same issue or have a similar script to fix?
Thanks again for this one!!

@itsanov
Copy link
Author

itsanov commented May 7, 2020

@Royrdan I'm glad that it helped somebody!
I'm also having the same issue with midline and crossline snapping. Unfortunately SketchUp is not throwing events in this case (or at least I could not find such) in order to repaint the screen. If you zoom enough, then screen refresh works fine for snapping.
I'm also annoyed by CPU usage of SketchUp in Wine, but it is usable.
By the way, credits go to @DSDev-NickHogle. I just expanded what he has started.

@mackinlay53
Copy link

@itsanov Thank you for your terrific work here. I was going crazy with the one mouse click delay to refresh the screen...I'm running SU 2017 Make under Wine 5.10. I had the same issues, but with your extension installed it has magically solved that problem!

I still see some lag in retrieving the endpoints, mid-points, etc. when trying to select an object, but it does seem better when I zoom in. All in all, this is not a huge deal and it seems like I can now run SU2017 on my Linux Mint 20 (Cinnamon) system just fine!

Thank you very much!

@itsanov
Copy link
Author

itsanov commented Dec 23, 2020

@Royrdan @mackinlay53 and everyone else using SketchUp under Wine, I have updated the script to fix the slow Import. I have also added a possibility to enable/disable the refresh fix from Plugins menu.

@mackinlay53
Copy link

mackinlay53 commented Dec 23, 2020 via email

@itsanov
Copy link
Author

itsanov commented Dec 23, 2020

@mackinlay53
Hi Patrick,
Style changing should be OK now.
Best,
Ivo

@mackinlay53
Copy link

mackinlay53 commented Dec 24, 2020 via email

@xyen2001
Copy link

Thank you very much. This is a great help.
YEN

@itsanov
Copy link
Author

itsanov commented Mar 24, 2021

Thank you very much. This is a great help.
YEN

Nice to hear that, YEN! Thank you!

@stombi
Copy link

stombi commented Aug 18, 2021

Perfect script! Thank you so much @itsanov !
For those who wonder how to make rbz from rb, just do this:
zip fix_sketchup_wine.rbz fix_sketchup_wine.rb

@kampos
Copy link

kampos commented Jan 29, 2022

Very good work, Thanks.

@dgm
Copy link

dgm commented Jan 30, 2022

How do I install this?

@xyen2001
Copy link

xyen2001 commented Feb 3, 2022

@dgm
Make a file "fix_sketchup_wine.rb" as above.
Place the file in /Plugins filder,
in my case :~/.wine/drive_c/users/y/Application Data/SketchUp/SketchUp 2016/SketchUp/Plugins/
Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment