Skip to content

Instantly share code, notes, and snippets.

@itsanov
Forked from DSDev-NickHogle/fix_sketchup_wine.rb
Last active July 14, 2023 11:33
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save itsanov/a6b9016dff5a5c0ee270ff8b82ebf66f to your computer and use it in GitHub Desktop.
Save itsanov/a6b9016dff5a5c0ee270ff8b82ebf66f to your computer and use it in GitHub Desktop.
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)
@itsanov
Copy link
Author

itsanov commented Jul 9, 2023

Thanks! There is still a problem that after I try to select something within a rectangle but nothing falls into it and the selection was not actually changed then that rectangle remains on the screen after I release my left mouse button.

Hi, @busyBeaver1 ,
I doubt it will be possible to fix this. Anyway, I will take a look next weekend. Which SketchUp version you use?
Best,
Ivo

@itsanov
Copy link
Author

itsanov commented Jul 9, 2023

You have no idea how wonderful this bug fix in Wine is for me!

Thank you for the nice words @brianinthered!
Unfortunately this fix is not applicable or translateable to Photoshop.
This script is actually a SketchUp plugin, which uses the SketchUp API to redraw the screen on user action. It might be possible to do something similar for Photoshop, but it will be completely different. You can try to contact somebody with photoshop plugin experience.
Actually the problem is somewhere in the Wine implementation and the best option would be to contact the Wine developers.
Making video to help more SketchUp linux users is great. That's why this script is shared here in the first place. I would suggest to include the SketchUp instalation into the video as well.
Best,
Ivo

@brianinthered
Copy link

brianinthered commented Jul 10, 2023

Here is the short video I uploaded with instructions on how to install the plugin
https://youtu.be/sBG-eB576DM

I do have instructions on how to install SketchUp in PlayOnLinux, but they are from 2014.
http://www.gamersonlinux.com/forum/threads/sketchup-guide.828/

I really do not recommend the guide because it uses an old version of PlayOnLinux and an old version of Wine. Not to mention SketchUp Make 2017 is no longer available for download and the guide recommends SkechUp 32-bit. I kept an old copy for myself, which is what I'm using today.

Most of the steps still apply, but if anyone has questions I can help on GamersOnLinux as I have posted all the step-by-step guides for the last 9 years or so.

[edit] Updated the youtube link to my personal channel

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